2013-02-05 16 views
6

Ich habe eine benutzerdefinierte Usercontrol SongDescription genannt:WPF Bindung an Usercontrol Benutzerdefinierte DependencyProperty

<UserControl x:Class="DPTestAp.SongDescription" ...> 
    <Grid x:Name="LayoutRoot"> 
     <DockPanel Height="50"> 
      <TextBlock x:Name="title" Text="{Binding name}" Width="100" Height="30"/> 
      <TextBox x:Name="lyrics"/> 
     </DockPanel> 
    </Grid> 
</UserControl> 

Ich habe DependencyProperty es:

public partial class SongDescription : UserControl 
{ 
    public static readonly DependencyProperty SongProperty = DependencyProperty.Register("Song", typeof(Song), typeof(SongDescription)); 

    public Song Song 
    { 
     get 
     { 
      return (Song)GetValue(SongProperty); 
     } 
     set 
     { 
      SetValue(SongProperty, value); 
      updateLyrics() 
     } 
    } 

    private void updateLyrics() 
    { 
     lyrics.Text = Song.lyrics; 
    } 

    public SongDescription() 
    { 
     InitializeComponent(); 
    } 
} 

Die Frage ist: wie etwas zu diesem SongProperty binden? Ich benutze SongDescription in meinem Hauptfenster wie folgt aus:

<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/> 

Ich kann nicht meine TextBox Texte Show Texte machen. Im Hauptfenster habe ich versucht, Datacontext songDescription, wie dies zu setzen:

songDescription.DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" }; 

oder Fenster selbst wie folgt aus:

DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" }; 

Ich habe sogar versucht, eine Ressource zu machen Lied und binden Sie es an SongProperty wie diese :

<Window.Resources> 
    <local:Song x:Key="res" name="Home" lyrics="Hold on, to me as we go"/> 
</Window.Resources> 
<Grid> 
    <local:SongDescription x:Name="songDescription" Song="{StaticResource res}"/> 
</Grid> 

Nichts half. TextBlock Titel bindet Song-Name in Ordnung. Aber ich kann updateLyrics() -Methode nicht aufrufen. (Im wirklichen Leben ist diese Methode komplizierter, daher kann ich Binding nicht wie mit Namen verwenden).

Vielen Dank!

Antwort

7

Yup, das ist also eine Frage mit Abhängigkeitseigenschaften. Sie nie setzen Sie Validierungscode innerhalb der Accessor-Methoden (get/set), weil Abhängigkeitseigenschaften von WPF in einer Tabelle gespeichert werden, die es selbst verwaltet. Aus diesem Grund müssen Sie die Abhängigkeitseigenschaften registrieren, im Wesentlichen werden Einträge in dieser Tabelle zum Speichern der Werte erstellt, die den einzelnen Eigenschaften zugeordnet sind. Wenn Sie 'GetValue'/'SetValue' verwenden, aktualisieren Sie die Einträge in dieser Tabelle (übrigens bezieht sich darauf, wie WPF Datenbindungen im Allgemeinen verwalten kann).

Das Ergebnis davon ist, dass WPF Ihre Eigenschaft Accessors vollständig umgehen kann (und wird), da es direkten Zugriff auf die realen Daten hat. Warum sollte es Ihre Accessoren verwenden, wenn es direkt zu den Daten gehen kann? Stattdessen müssen Sie eine "PropertyChanged" -Rückruffunktion oder eine WPF-sanktionierte Validierungsmethode implementieren, aber tun Sie dies nie in Ihren Accessoren.

See:

http://msdn.microsoft.com/en-us/library/ms752914.aspx

+0

Danke, Meister! –

+0

aber dann ist 'PropertyChanged' Callback, ich kann kein Steuerelement aktualisieren, weil es eine gemeinsame Funktion ist! –

2

Neben sircodesalot Antwort, die Sie auf Ihrem Text Textbox nicht gebunden. Da der Song, an den Sie gebunden sind, eine Klasse ist, müssen Sie die Pfade für die Eigenschaften, die Sie in den Feldern anzeigen möchten, wie "Pfad = Song.Lyrik", vollständig angeben.

Eine andere Sache zu berücksichtigen ist, dass mit Abhängigkeitseigenschaften; Ihr Modus wird standardmäßig einweg sein, so dass das Textfeld editierbar sein würde, wenn Sie es nicht ändern.

Drittens, wenn Sie MVVM verwenden, müssen Sie nur Ihren Hauptfensterkontext auf das Ansichtsmodell einstellen und eine passende Song-Eigenschaft haben, an die gebunden werden soll.

Verwandte Themen