2013-06-07 19 views
9

Utworzyłem UserControl z niektórymi DependencyProperties (w tym przykładzie jest to tylko jedna właściwość łańcucha znaków). Kiedy tworzę instancję UserControl, mogę ustawić właściwość UserControl i jest ona pokazywana zgodnie z oczekiwaniami. Kiedy próbuję zastąpić tekst statyczny przez powiązanie, nic nie jest wyświetlane.Powiązanie z UserControl DependencyProperty

My UserControl wygląda następująco:

<User Control x:Class="TestUserControBinding.MyUserControl" 
      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:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="30" d:DesignWidth="100"> 
    <Grid> 
    <Label Content="{Binding MyText}"/> 
    </Grid> 
</UserControl> 

Kodeks Za to:

namespace TestUserControBinding { 

    public partial class MyUserControl : UserControl { 
    public MyUserControl() { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 

    public static readonly DependencyProperty MyTextProperty = 
        DependencyProperty.Register(
         "MyText", 
          typeof(string), 
          typeof(MyUserControl)); 

    public string MyText { 
     get { 
     return (string)GetValue(MyTextProperty); 
     } 
     set { 
     SetValue(MyTextProperty, value); 
     } 
    }// MyText 

    } 
} 

Kiedy próbuję to w moim MainWindow, wszystko jest zgodnie z oczekiwaniami:

<Window x:Class="TestUserControBinding.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TestUserControBinding" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
    <local:MyUserControl MyText="Hello World!"/> 
    </StackPanel> 
</Window> 

Ale to nie działa:

<Window x:Class="TestUserControBinding.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TestUserControBinding" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
    <local:MyUserControl MyText="{Binding Path=Text}"/> 
    <Label Content="{Binding Path=Text}"/> 
    </StackPanel> 
</Window> 

Zachowanie etykiecie jest prawidłowy, więc nie ma problemu z „text” Property

Jaki jest mój błąd? Zastanawiam się przez wiele godzin, ale nie mogę znaleźć niczego, o czym zapomniałem.

Odpowiedz

10

z następującymi wiążąca w swojej UserControl:

<Label Content="{Binding MyText}"/> 

Nie jestem pewien, jak ustawienie tekstu bezpośrednio do prac własności myText. Musisz ustawić DataContext na UserControl gdzieś, aby to zadziałało.

Bez względu na to powiązanie jest problemem - ponieważ rozumiem Twój scenariusz, nie chcesz wiązać się z DataContext z UserControl, ponieważ nie musi to mieć własności MyText. Chcesz połączyć się z samym UserControl, a konkretnie utworzonym DependencyProperty. Aby to zrobić, trzeba użyć RelativeSource wiążące, jak następuje:

<Label Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=MyText}"/> 

To będzie poruszać się w górę drzewa wizualnej MyUserControl a następnie znaleźć właściwość myText tam. Nie będzie zależny od DataContext, który zmieni się w zależności od miejsca, w którym umieścisz UserControl.

W tym przypadku local odnosi się do nazw trzeba określić w UserControl:

<UserControl x:Class="TestUserControBinding.MyUserControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TestUserControBinding" 
     ...> 

A twój drugi przykład powinien działać w tym punkcie.

+0

@ Brian ... Kod "this.DataContext = this;" powinien zadbać o ustawienie DataContext na lokalny. Czy nie powinien? – Nishant

+4

Och, tak, tęskniłem za tym. Ale jeśli tworzysz 'UserControl', nie sądzę, że dobrym pomysłem jest ręczne ustawienie' DataContext'. "DataContext" ma reprezentować kontekst odziedziczony lub przypisany z kontenera. Powiązanie 'RelativeSource' pozwala osiągnąć pożądany wynik (powiązanie z' DependencyProperty'), nie przerywając standardowego przepływu dziedziczenia 'DataContext'. Próba zastąpienia 'DataContext', jak masz, nie powiedzie się, jeśli konsument twojego' UserControl' ustawi własny 'DataContext'. –

+2

to był dokładnie problem.Zamiast ustawiać DataContext MyUserControl sobie używam teraz 'x: Name = "MyName"' w znaczniku otwierającym 'MyUserControl' i wiązanie zmian:'

Powiązane problemy