2013-06-07 23 views
9

Ich habe ein UserControl mit einigen DependencyProperties erstellt (im Beispiel hier nur eine String-Eigenschaft). Wenn ich die Benutzersteuerung instanziiere, kann ich die Eigenschaft von dem Benutzersteuerelement festlegen und es wird wie erwartet angezeigt. Wenn ich versuche, den statischen Text durch Binding zu ersetzen, wird nichts angezeigt.Bindung an UserControl DependencyProperty

Mein Usercontrol sieht wie folgt aus:

<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> 

der Code-behind ist:

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 

    } 
} 

Wenn ich das versuche in meinem Mainwindow, ist alles wie erwartet:

<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> 

Aber das funktioniert nicht:

<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> 

Das Verhalten des Etiketts richtig ist, so gibt es kein Problem mit der Eigenschaft „Text“

Was mein Fehler ist? Ich denke stundenlang nach, kann aber nichts finden, was ich vergessen habe.

Antwort

10

Mit der folgenden Bindung in Ihrem UserControl:

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

Ich bin nicht sicher, wie der Text direkt auf die Eigenschaft Werke MyText Einstellung. Sie müssen den DataContext auf dem UserControl irgendwo dafür einstellen, damit das funktioniert.

Egal, diese Bindung ist das Problem - wie ich Ihr Szenario verstehe, möchten Sie nicht an die DataContext der UserControl binden, weil das nicht unbedingt eine MyText-Eigenschaft haben wird. Sie möchten an die UserControl selbst binden und speziell an die von Ihnen erstellte DependencyProperty. Um das zu tun, müssen Sie eine RelativeSource Bindung verwenden, wie die folgenden:

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

Dies wird die visuelle Struktur navigieren bis MyUserControl und dann die MyText Eigenschaft dort zu finden. Es hängt nicht von der DataContext ab, die sich je nachdem ändert, wo Sie die UserControl platzieren.

In diesem Fall bezieht sich local auf einen Namespace Sie im UserControl zu definieren brauchen werden:

<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" 
     ...> 

Und Ihr zweites Beispiel sollte an diesem Punkt arbeiten.

+0

@Brian ... Der Code "this.DataContext = this;" sollte darauf achten, den DataContext auf local zu setzen. Sollte es nicht? – Nishant

+4

Oh, ja, das habe ich verpasst. Aber wenn Sie ein 'UserControl' erstellen, ist es keine gute Idee, den' DataContext' manuell zu setzen. Der 'DataContext' soll den Kontext darstellen, der vom Container geerbt oder zugewiesen wurde. Mit der 'RelativeSource'-Bindung können Sie das gewünschte Ergebnis (Bindung an die' DependencyProperty') erreichen, ohne den Standard 'DataContext'-Vererbungsfluss zu unterbrechen. Der Versuch, den 'DataContext' zu überschreiben, scheitert, wenn der Consumer von' UserControl' seinen eigenen 'DataContext' definiert. –

+2

das war genau das Problem.Anstatt den DataContext von MyUserControl auf sich selbst zu setzen, benutze ich jetzt 'x: Name =" MyName "' im öffnenden Tag von 'MyUserControl' und die Binding ändert sich zu:'

Verwandte Themen