2011-09-27 8 views
12

Mam podstawowe UserControl który ustawia swój DataContext sobie łatwość wiązania:Ustawianie DataContext w UserControl wpływa powiązania z rodzicem

<UserControl x:Class="MyControlLib.ChildControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 

      DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

</UserControl> 

ta jest wykorzystywana w pliku rodzic XAML tak:

<UserControl x:Class="MyControlLib.ParentControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:ctrl="clr-namespace:MyControlLib"> 

      <ctrl:ChildControl x:Name="ChildName" 
           PropertyOnChild="{Binding PropertyInParentContext}"/>    
</UserControl> 

Z jakiegoś powodu daje to błąd wiążący, który wydaje się wskazywać, że ustawienie kontroli podrzędnej ma wpływ na ustawienie DataContext kontroli rodzicielskiej: DataContext.

System.Windows.Data Error: 40 : BindingExpression path error: 'PropertyInParentContext' property not found on 'object' ''ChildControl' (Name='ChildName')'. BindingExpression:Path=PropertyInParentContext; DataItem='ChildControl' (Name='ChildName'); target element is 'ChildControl' (Name='ChildName'); target property is 'PropertyOnChild' (type 'whatever')

Dlaczego „PropertyInParentContext” bycie szuka w kontroli dziecka niż w macierzystej DataContext?

Jeśli usunąć

DataContext="{Binding RelativeSource={RelativeSource Self}} 

od kontroli dziecka, potem wszystko działa jak by się spodziewać.

Czy brakuje tu czegoś oczywistego?

Odpowiedz

11

Deklaracja twojej kontroli i instancji są w zasadzie manipulujące tym samym obiektem, wszystkie właściwości, które są ustawione w deklaracji, są również ustawione dla każdej instancji. Więc jeśli właściwości są „widoczne” że tak powiem:

<UserControl x:Class="MyControlLib.ParentControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:ctrl="clr-namespace:MyControlLib"> 
    <ctrl:ChildControl x:Name="ChildName" 
         DataContext="{Binding RelativeSource={RelativeSource Self}}" 
         PropertyOnChild="{Binding PropertyInParentContext}"/> 
</UserControl> 

To dlaczego nie ustawić DataContext z UserControls, to przesłonić odziedziczoną DataContext (a nawet zaciemnić fakt, że istnieje inny kontekst) . Jeśli chcesz powiązać właściwości deklaracji UserControl, wymień nazwę kontrolki i użyj linków typu ElementName lub RelativeSource.

+0

Dzięki, nie zrozumiałem zakresu wiązań i twój post wyjaśnił to całkiem dobrze. Myślałem, że XAML z UserControl jest samowystarczalny, jak w szablonie, ale myślę, że to tylko część dokumentu. – GazTheDestroyer

5

Self oznacza UserControl, więc po ustawieniu DataContext do Self, jesteś ustawienie DataContext do obiektu UserControl.

Poprawną składnią dla powiązania kontroli z DataContext będzie {Binding RelativeSource={RelativeSource Self}, Path=DataContext}, jednak ponieważ DataContext jest dziedziczony przez Parent, to powiązanie jest całkowicie niepotrzebne w żadnej sytuacji.

Ponadto, jeśli wiążesz swoje DataContext z Self.DataContext, zasadniczo tworzysz pętlę, w której wartość jest związana z samą sobą.

+0

Tak, to było dokładnie to, co próbowałem zrobić - ustawić DataContext na UserControl. Nie rozumiałem, że wpłynie to na wiążące stwierdzenia w kontroli "rodzicielskiej". – GazTheDestroyer