2010-12-28 5 views
6

Sto giocando con il binding e le variabili di WPF. Apparentemente si può solo legare proprietà di dipendenza. Sono venuto con la seguente, che funziona perfettamente bene: Il file code-behind:WPF Rilegatura a variabile/Dipendenza Proprietà

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    public string Test 
    { 
     get { return (string)this.GetValue(TestProperty); } 
     set { this.SetValue(TestProperty, value); } 
     //set { this.SetValue(TestProperty, "BBB"); } 
    } 
    public static readonly DependencyProperty TestProperty = DependencyProperty.Register(
     "Test", typeof(string), typeof(MainWindow), new PropertyMetadata("CCC")); 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     MessageBox.Show(Test); 
     Test = "AAA"; 
     MessageBox.Show(Test); 
    } 
} 

XAML:

<Window x:Class="WpfApplication3.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase" 
    Title="MainWindow" Height="350" Width="525" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
<Grid> 
    <TextBox Height="31" HorizontalAlignment="Left" Margin="84,86,0,0" Name="textBox1" VerticalAlignment="Top" Width="152" 
      Text="{Binding Test, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}"/> 
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="320,85,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /> 
    <TextBox Height="31" HorizontalAlignment="Left" Margin="84,138,0,0" Name="textBox2" Text="{Binding Test, Mode=TwoWay}" VerticalAlignment="Top" Width="152" /> 
</Grid> 

I due TextBoxes aggiornare uno un altro. E il pulsante li imposta su "AAA".

Ma ora ho sostituito la funzione Setter con quella che è stata commentata (simulando qualche manipolazione del valore dato). Mi aspetto che ogni volta che viene modificato il valore della proprietà verrà reimpostato su "BBB". Lo fa quando si preme il pulsante, cioè quando si imposta la proprietà nel codice. Ma per qualche ragione non influisce sui binding WPF, cioè puoi modificare il contenuto del TextBox e quindi la proprietà, ma apparentemente il Setter non viene mai chiamato. Mi chiedo perché sia ​​così, e come si andrebbe a ottenere il comportamento previsto.

+0

possibile duplicato di [WPF: proprietà XAML dichiarazioni non impostate tramite setter?] (http://stackoverflow.com/questions/3836076/wpf-xaml-property-declarations-not-being-set-via-setters) –

risposta

13

Il wrapper di proprietà CLR per una proprietà di dipendenza non viene mai garantito per essere chiamato e pertanto non si dovrebbe mai inserire alcuna logica aggiuntiva. Ogni volta che è necessaria una logica aggiuntiva quando viene modificato un DP, è necessario utilizzare la callback modificata proprietà.

Nel tuo caso ..

public string Test 
{ 
    get { return (string)this.GetValue(TestProperty); } 
    set { this.SetValue(TestProperty, value); } 
} 

public static readonly DependencyProperty TestProperty = 
    DependencyProperty.Register("Test", 
    typeof(string), 
    typeof(MainWindow), 
    new PropertyMetadata("CCC", TestPropertyChanged)); 

private static void TestPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
{ 
    MainWindow mainWindow = source as MainWindow; 
    string newValue = e.NewValue as string; 
    // Do additional logic 
} 
2

La modifica non influenzerà l'associazione, perché il XAML chiamerà ImpostaValore direttamente, invece di chiamare il vostro setter.That proprietà è come il sistema proprietà di dipendenza works.When una dipendenza la proprietà è registrata, è possibile specificare un valore predefinito. Questo valore viene restituito da GetValue ed è il valore predefinito per la proprietà.

Controllare sul link qui sotto e leggere al post di Robert Rossney per avere una panoramica fiera

WPF: What distinguishes a Dependency Property from a regular CLR Property?

anche da non perdere

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

e

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

Si noti inoltre che a differenza di normali proprietà CLR qualsiasi logica personalizzata si scrive nel setter non verrà eseguita in proprietà di dipendenza, invece è necessario utilizzare il meccanismo PropertyChangedCallback

http://blogs.msdn.com/b/delay/archive/2010/03/23/do-one-thing-and-do-it-well-tip-the-clr-wrapper-for-a-dependencyproperty-should-do-its-job-and-nothing-more.aspx