2013-02-05 19 views
6

Ho un UserControl personalizzata denominata SongDescription:WPF Associazione a UserControl personalizzato 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> 

ho aggiunto DependencyProperty ad esso:

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(); 
    } 
} 

La domanda è: come associare qualcosa a questo SongProperty? Io uso SongDescription nella mia finestra principale in questo modo:

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

non riesco a fare il mio TextBox testi spettacolo testi. Nella finestra principale ho cercato di impostare DataContext a songDescription, in questo modo:

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

o finestra stessa in questo modo:

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

ho anche provato a fare canzone una risorsa e associarlo al SongProperty come questo :

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

Niente di utile. TextBlock title associa il nome del brano. Ma non posso far chiamare il metodo updateLyrics(). (Nella vita reale questo metodo è più complicato, quindi non posso usare Binding come con il nome).

Grazie!

risposta

7

Sì, è un trucco con proprietà di dipendenza. Si mai e poi mai inserire il codice di convalida all'interno dei metodi accessor (get/set) perché le proprietà di dipendenza vengono archiviate da WPF in una tabella gestita da se stessa. Questo è il motivo per cui devi registrare le proprietà di dipendenza, in sostanza crea voci su questa tabella per memorizzare i valori associati a ciascuna proprietà, e quando usi 'GetValue'/'SetValue' stai aggiornando le voci su questa tabella (che tra l'altro si riferisce a come WPF è in grado di gestire i binding di dati in generale).

Il risultato è che WPF può (e sarà) bypassare completamente i propri accessor di proprietà perché ha accesso diretto ai dati reali. Perché dovrebbe usare i tuoi accessors se può andare direttamente ai dati. Invece è necessario implementare una funzione di callback 'PropertyChanged' o un qualche metodo sanzionato WPF di validazione, ma non farlo mai mai nei tuoi accessor.

See:

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

+0

Grazie, maestro! –

+0

ma poi, è il callback 'PropertyChanged', non sarò in grado di aggiornare alcun controllo, perché è una funzione condivisa! –

2

Oltre alla risposta di sircodesalot, non sono tenuti sul testi casella di testo. Inoltre, poiché il brano a cui è associato è una classe, dovrai specificare i percorsi completamente per le proprietà che desideri mostrare nelle caselle come "Path = Song.Lyrics".

Un'altra cosa da considerare è che con le proprietà di dipendenza; la tua modalità sarà oneway per impostazione predefinita, quindi rendere il campo di testo modificabile sarebbe veramente discutibile a meno che non lo cambi.

In terzo luogo, se si utilizza MVVM, è necessario impostare il contesto della finestra principale sul modello di visualizzazione e associare una proprietà Song corrispondente.

Problemi correlati