2010-06-24 79 views
0

我目前正在努力與我想添加到我的WPF項目的綁定之一。 在應用程序中,我有一個不能用於數據綁定的bool屬性的模型。該屬性後面是一個.NET Remoting對象,它執行一些驗證並將新值寫入數據庫。綁定的價值變化直接存儲在數據庫中

需要確保屬性應顯示爲複選框,並且隨着用戶更改值,新值應立即提供給.NET遠程處理對象。

我到目前爲止的方法: 我在我的ViewModel中創建了一個綁定到我的複選框的DependencyProperty。 在DP的propertychanged處理程序中,我正在將值寫入遠程處理對象的屬性。

我對這種方法存在的問題: 如果.net遠程處理對象內的驗證引發異常,則會吞噬此異常。此外,複選框狀態和數據庫中的內容不同步。如果發生異常,我嘗試重置DP的值,但該複選框沒有反映出該值。 是什麼讓情況變得更糟?事實是,這個WPF控件被集成到了現有的WinForms應用程序中。 所以我想對這些異常具有相同的行爲,因爲我在Application.ThreadException處理程序中實現了這些行爲。

任何想法如何處理這個? 問題是,目前爲止我只聽說過.NET 4.0的解決方案,但我正在使用3.5SP1。

TIA 馬丁

簡短的演示代碼:

class TestVM : DependencyObject 
{ 
private Model _m; 
public TestVM() 
{ 
    _m = new Model(); 
} 

public bool Value 
{ 
    get { return (bool)GetValue(ValueProperty); } 
    set { SetValue(ValueProperty, value); } 
} 

// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty ValueProperty = 
    DependencyProperty.Register("Value", 
       typeof(bool), 
       typeof(TestVM), 
       new FrameworkPropertyMetadata(
        false, 
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
        ((sender, e) => ((TestVM)sender).Apply(e)))); 

private bool _suppress = false; 
private void Apply(DependencyPropertyChangedEventArgs e) 
{ 
    if (_suppress) return; 
    try 
    { 
    _m.Value = this.Value; 
    } 
    catch 
    { 
    _suppress = true; 
    this.Value = _m.Value; 
    this.OnPropertyChanged(e); 
    } 
    finally 
    { 
    _suppress = false; 
    } 
} 

}

回答

0

我找到了我的問題的解決方案。我現在正在派生我自己的綁定類來完成這項工作。

public class ExceptionBinding : Binding 
{ 
    public ExceptionBinding(string name) 
     : base(name) 
    { 
     Construct(); 
    } 

    public ExceptionBinding() 
     : base() 
    { 
     Construct(); 
    } 

    private void Construct() 
    { 
     this.ValidatesOnExceptions = true; 
     this.UpdateSourceExceptionFilter = new UpdateSourceExceptionFilterCallback(OnException); 
    } 

    private object OnException(object bindExpression, Exception exception) 
    { 
     // ... custom error display ... 
     var exp = (BindingExpressionBase)bindExpression; 
     exp.UpdateTarget(); 
     return null; // null needed to avoid display of the default error template 
    } 
} 
0

你並不需要使用的DependencyObject爲您的視圖模型。你只需要執行INotifyPropertyChanged獲取數據綁定支持:

class TestVM 
    : INotifyPropertyChanged 
{ 
    private Model _m; 
    public TestVM() 
    { 
     _m = new Model(); 
    } 

    public bool Value 
    { 
     get { return _m.Value; } 
     set 
     { 
      _m.Value = this.Value; 
      OnPropertyChanged("Value"); 
     } 
    } 

    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

請注意,如果你期望的setter拋出異常,你可能要在視圖中的結合使用ExceptionValidationRule


更新:這聽起來像你的問題是,綁定將不會對事件的PropertyChanged響應調用中設置源。解決此問題的一種方法是通過在XAML中設置IsAsync=True來實現綁定,從而使用異步綁定。 WPF將在更新源值後處理PropertyChanged事件,並且不會認爲它是可重入的調用。

你也可以通過使用轉換器來解決此問題,並通過執行UpdateSourceTrigger=LostFocus關閉PropertyChanged上的更新,但我不認爲你會想要這種行爲。

+0

抱歉,但這不起作用,即使我得到異常,並在最後調用OnPropertyChanged,複選框並不反映未更新的值。 – 2010-06-24 15:01:53