代码之家  ›  专栏  ›  技术社区  ›  Martin Moser

值更改直接存储在数据库中的绑定

  •  0
  • Martin Moser  · 技术社区  · 14 年前

    我目前正努力将其中一个绑定添加到我的WPF项目中。

    我目前的做法是: 我在ViewModel中创建了一个DependencyProperty,它绑定到我的复选框。

    我在这种方法中遇到的问题是: 如果.net远程处理对象内的验证引发异常,则该异常将被忽略。此外,复选框状态和数据库中的内容不同步。我试图在出现异常时重置DP的值,但是复选框没有反映出这一点。 因此,我希望这些异常的行为与我在Application.ThreadException处理程序中实现的行为相同。

    有什么办法吗? 问题是到目前为止我只听说了.NET4.0的解决方案,但我使用的是3.5SP1。

    短暂性脑缺血发作 马丁

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

    }

    2 回复  |  直到 14 年前
        1
  •  0
  •   Quartermeister    14 年前

    您不需要将DependencyObject用作ViewModel。您只需实现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;
    }
    

    ExceptionValidationRule 在你的视野里。


    更新:听起来您的问题是绑定在设置源的调用中不会响应PropertyChanged事件。解决这个问题的一种方法是通过设置 IsAsync=True

    您还可以通过使用转换器和关闭PropertyChanged上的更新来绕过此问题 UpdateSourceTrigger=LostFocus

        2
  •  0
  •   Martin Moser    14 年前

    我找到了解决问题的办法。我现在正在派生自己的绑定类来完成这项工作。

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