2012-06-22 26 views
0

我想,一旦我改變了txtA的值,txtB和txtC就會自動改變,因爲我已經爲ValueA實現了INotifyPropertyChanged。WPF/INotifyPropertyChanged,更改txtA的值,txtB和txtC應該自動更改?

但它們沒有在UI上更新。 txtB始終爲100,txtC始終爲-50。

我不知道是什麼原因。

我的XAML ..

<Window x:Class="WpfApplicationReviewDemo.MainWindow" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Title="MainWindow" Height="350" Width="525"> 
     <StackPanel> 
      <TextBox Name="txtA" Text="{Binding ValueA}" /> 
      <TextBox Name="txtB" Text="{Binding ValueB}" /> 
      <TextBox Name="txtC" Text="{Binding ValueC}" /> 
     </StackPanel> 
    </Window> 

我的代碼背後...

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

     this.DataContext = new Model(); 
    } 
} 


public class Model : INotifyPropertyChanged 
{ 
    private decimal valueA; 
    public decimal ValueA { get { 
     return valueA; 
    } 
     set 
     { 
      valueA = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueA")); 
     } 
    } 

    private decimal valueB; 
    public decimal ValueB 
    { 
     get 
     { 
      valueB = ValueA + 100; 
      return valueB; 
     } 
     set 
     { 
      valueB = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueB")); 
     } 
    } 


    private decimal valueC; 
    public decimal ValueC 
    { 
     get 
     { 
      valueC = ValueA - 50; 
      return valueC; 
     } 
     set 
     { 
      valueC = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueC")); 
     } 
    } 


    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 

後,我到值a屬性的set方法添加代碼,它的工作原理。

public decimal ValueA { get { 
     return valueA; 
    } 
     set 
     { 
      valueA = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueA")); 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueB")); 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueC")); 
     } 
    } 

但我應該自動刷新/更新txtB和txtC。請指教。

回答

1

開箱,它不知道屬性B & C是依賴於A.你需要告訴它,就像你已經完成。

1

PropertyChanged允許任何數據綁定到屬性已更改的對象。當您更改文本框的值時,請遵循代碼的邏輯。爲ValueA調用set方法,並將valueA設置爲value。

set 
{ 
    valueA = value; 
    PropertyChanged(this, new PropertyChangedEventArgs("ValueA")); 
} 

然而,當的PropertyChanged被調用,它的作用是讓文本框知道值改變(的東西,它已經知道,因爲它叫set方法)。其他第二組方法工作的原因是它通知其他文本框,它們的屬性也發生了變化,所以它們需要反映這些變化。

set 
{ 
    valueA = value; 
    PropertyChanged(this, new PropertyChangedEventArgs("ValueA")); 
    PropertyChanged(this, new PropertyChangedEventArgs("ValueB")); 
    PropertyChanged(this, new PropertyChangedEventArgs("ValueC")); 
} 

這讓所有三個文本框更新顯示以顯示新值。

+0

我見過很多人說,你的做法,這是一個反模式。他們聲稱您應該實現一種模式,您可以通過屬性等來定義「INotify」依賴關係。例如,定義ValueB依賴於ValueA,而不是讓ValueA必須知道依賴於它的所有內容。就我個人而言,我經常使用你的方法,因爲它非常簡單,這就是爲什麼我投票給你。 – Nogusta

+0

@Nogusta謝謝。而且,我自己實際上並沒有寫任何代碼。如果我正確地閱讀了這個問題,這個問題只是要求解釋爲什麼一種方式比另一種更好。他自己寫了兩個片段。 Model2的 –

3

我會處理這無論是作爲

public class Model : INotifyPropertyChanged 
{ 
    private decimal valueA; 

    public decimal ValueA 
    { 
     get { return valueA; } 
     set 
     { 
      if(valueA != value) 
      { 
       valueA = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("ValueA")); 
       PropertyChanged(this, new PropertyChangedEventArgs("ValueB")); 
       PropertyChanged(this, new PropertyChangedEventArgs("ValueC")); 
      } 
     } 
    } 

    public decimal ValueB 
    { 
     get { return ValueA + 100; } 
    } 

    public decimal ValueC 
    { 
     get { return ValueA - 50; } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 

public class Model2 : INotifyPropertyChanged 
{ 
    private decimal valueA; 
    private decimal valueB; 
    private decimal valueC; 

    public decimal ValueA 
    { 
     get { return valueA; } 
     set 
     { 
      if(valueA != value) 
      { 
       valueA = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("ValueA")); 

       ValueB = value + 100; 
       ValueC = value - 50; 
      } 
     } 
    } 

    public decimal ValueB 
    { 
     get { return valueB; } 
     private set 
     { 
      valueB = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueB")); 
     } 
    } 

    public decimal ValueC 
    { 
     get { return valueC; } 
     private set 
     { 
      valueC = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("ValueC")); 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 
+0

+1;) – blindmeis

0

你正在談論通常refered爲「計算」或「計算」性質的情況。但是,通常建議將它們設置爲只讀。只讀計算簡化了您的代碼,並且意味着您不需要有一個後臺字段來存儲該值。

正如你所做的那樣,INotifyPropertyChanged不會「自動地」檢測這些依賴關係。您需要根據依賴關係顯式激發事件。

這實際上是使用ILWeaving的最佳例子。原因是在編譯時,ILWeaving可以檢測這些依賴關係並正確激發多個事件。

例如,如果您使用NotifyPropertyWeaver http://code.google.com/p/notifypropertyweaver/,您可以像這樣編寫代碼。

public class Model : INotifyPropertyChanged 
{ 
    public decimal ValueA { get; set; } 

    public decimal ValueB 
    { 
     get { return ValueA + 100;} 
    } 

    public decimal ValueC 
    { 
     get { return ValueA - 50; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

,並已編制本

public class Model : INotifyPropertyChanged 
{ 
    public virtual void OnPropertyChanged(string propertyName) 
    { 
     var propertyChanged = PropertyChanged; 
     if (propertyChanged != null) 
     { 
      propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    decimal valueA; 

    public decimal ValueA 
    { 
     get { return valueA; } 
     set 
     { 
      if (!decimal.Equals(valueA, value)) 
      { 
       valueA = value; 
       OnPropertyChanged("ValueB"); 
       OnPropertyChanged("ValueC"); 
       OnPropertyChanged("ValueA"); 
      } 
     } 
    } 

    public decimal ValueB 
    { 
     get { return ValueA + 100;} 
    } 

    public decimal ValueC 
    { 
     get { return ValueA - 50; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

注意OnPropertyChanged已經與三個電話沿着注射方法是在二傳手爲「A」。

注意,「B」和「C」文本框也應該只讀

<TextBox Name="txtA" Text="{Binding ValueA}" /> 
    <TextBox Name="txtB" Text="{Binding ValueB}" IsReadOnly="True" /> 
    <TextBox Name="txtC" Text="{Binding ValueC}" IsReadOnly="True" />