2014-01-13 43 views
2

我有一個WPF應用程序,其中包含約50個控件,這些控件綁定到實現INotifyPropertyChanged的業務對象上的屬性。這裏是我的業務對象的一個​​快速片段:我也有幾個驗證規則用於驗證這些控件中的用戶輸入。如果有任何驗證錯誤,我使用命令綁定來阻止我的用戶保存數據。我的應用程序還包含一個「重置默認值」按鈕,顯然,它將重置業務對象上所有屬性的默認值。這一切正如我所願,只有一個例外。如果我的用戶將無效數據輸入到一個或多個控件中,然後單擊「重置默認值」按鈕,那麼包含無效數據的控件並不總是按照我的預期更新。發生這種情況是因爲在我的屬性setter以下代碼:強制使用GetBindingExpression()更新所有WPF綁定控件UpdateTarget()

if (_name == value) 
{ 
    return; 
} 

該代碼的存在是爲了防止不必要的屬性從當通過我的用戶在綁定UI控制輸入的值是相同的值,該場所中發生改變的通知已經設置爲。作爲一個例子,我在我的UI中有一個IntegerUpDown控件(這個控件是Xceed的擴展WPF工具包的一部分)。我的控件綁定的屬性的默認值爲10.我的用戶從控件中刪除了該值,並且觸發了驗證規則,導致驗證錯誤,並且使用錯誤裝飾器等適當更新UI。值該控件映射到的屬性沒有被更改,因此它仍然被設置爲10.現在我的用戶單擊「重置默認值」按鈕,這將導致屬性被重置的默認值(10)。但是,該屬性的值爲已經設置爲10,因此設置器中的短路邏輯將返回而不是設置屬性值。

所以,現在,我的用戶點擊後「恢復默認值」,我也迫使更新我的約束性指標是這樣的:

this.myIntegerUpDown.GetBindingExpression(Xceed.Wpf.Toolkit.IntegerUpDown.ValueProperty).UpdateTarget(); 

這解決了我的問題,但僅適用於這個特定的控制。有沒有簡單的方法來做到這一點所有我的約束控制,而不必指定每一個?謝謝。

+1

爲什麼不直接調用NotifyPropertyChanged(),在復位沒有任何參數,並且強制所有的更新。 50個控件不應該花那麼長時間。 – Paparazzi

+0

@Blam - 也是一個好主意。感謝您的建議。 – user685869

回答

6

OnPropertyChanged(new PropertyChangedEventArgs(string.Empty));

這旨在暗示該對象上的所有屬性已經改變。

0

只要總是調用OnPropertyChanged不管它是否相同,會不會更容易?這會給你帶來多大的性能提升?

+0

它肯定會更容易*。 :-)老實說,我不確定我在提供的短路邏輯中獲得了多少性能提升,但在編寫它的時候這似乎是個好主意。至少在我遇到這個問題之前,無論如何... – user685869

+0

我可能會發現你從第一個獲得的優勢有多大。我想可能不會太多。 – TylerD87

2

您可以做以下其中一項嗎?

1)復位DataContext - 經由反射要麼重新創建它,或重新設置該屬性

var context = this.DataContext; 
this.DataContext = null; 
this.DataContext = context; 

2)循環遍歷所有屬性編程和手動調用OnPropertyChanged與有關屬性名稱。

var properties = typeof(ViewModel).GetProperties(BindingFlags.Instance | BindingFlags.Public); 
foreach (var property in properties) 
{ 
    this.OnPropertyChanged(new PropertyChangedEventArgs(property.Name)); 
} 
+0

感謝您的建議。 – user685869

1

你已經提到了驗證和重置值,當然最明顯的是堅持它。

您爲什麼不實施IEditableObject接口您的實體上有三個簽名方法。 BeginEdit()的CancelEdit()和EndEdit中()

這樣,你可以很容易地想要回滾實體到什麼,或驗證它,最後它仍然存在。一個很好的例子是發現here

示例代碼

public class Customer : IEditableObject 
{ 

    struct CustomerData 
    { 
     internal string id ; 
     internal string firstName ; 
     internal string lastName ; 
    } 

    private CustomersList parent; 
    private CustomerData custData; 
    private CustomerData backupData; 
    private bool inTxn = false; 

    // Implements IEditableObject 
    void IEditableObject.BeginEdit() 
    { 
     Console.WriteLine("Start BeginEdit"); 
     if (!inTxn) 
     { 
      this.backupData = custData; 
      inTxn = true; 
      Console.WriteLine("BeginEdit - " + this.backupData.lastName); 
     } 
     Console.WriteLine("End BeginEdit"); 
    } 

    void IEditableObject.CancelEdit() 
    { 
     Console.WriteLine("Start CancelEdit"); 
     if (inTxn) 
     { 
      this.custData = backupData; 
      inTxn = false; 
      Console.WriteLine("CancelEdit - " + this.custData.lastName); 
     } 
     Console.WriteLine("End CancelEdit"); 
    } 

    void IEditableObject.EndEdit() 
    { 
     Console.WriteLine("Start EndEdit" + this.custData.id + this.custData.lastName); 
     if (inTxn) 
     { 
      backupData = new CustomerData(); 
      inTxn = false; 
      Console.WriteLine("Done EndEdit - " + this.custData.id + this.custData.lastName); 
     } 
     Console.WriteLine("End EndEdit"); 
    } 

    public Customer(string ID) : base() 
    { 
     this.custData = new CustomerData(); 
     this.custData.id = ID; 
     this.custData.firstName = ""; 
     this.custData.lastName = ""; 
    } 

    public string ID 
    { 
     get 
     { 
      return this.custData.id; 
     } 
    } 

    public string FirstName 
    { 
     get 
     { 
      return this.custData.firstName; 
     } 
     set 
     { 
      this.custData.firstName = value; 
      this.OnCustomerChanged(); 
     } 
    } 

    public string LastName 
    { 
     get 
     { 
      return this.custData.lastName; 
     } 
     set 
     { 
      this.custData.lastName = value; 
      this.OnCustomerChanged(); 
     } 
    } 

    internal CustomersList Parent 
    { 
     get 
     { 
      return parent; 
     } 
     set 
     { 
      parent = value ; 
     } 
    } 

    private void OnCustomerChanged() 
    { 
     if (!inTxn && Parent != null) 
     { 
      Parent.CustomerChanged(this); 
     } 
    } 

    public override string ToString() 
    { 
     StringWriter sb = new StringWriter(); 
     sb.Write(this.FirstName); 
     sb.Write(" "); 
     sb.Write(this.LastName); 
     return sb.ToString(); 
    } 
}