数据绑定属性触发PropertyChanged

时间:2016-08-10 18:47:04

标签: wpf data-binding dependency-properties datacontext inotifypropertychanged

我有一个View(UserControl),上面有两个用户控件:

  • 第一个UC是搜索控件
  • 第二个UC是一个细节控制

当我在搜索控件中选择一个DataGrid行时,我将此选定的项绑定到详细控件 - 这一切都正常。

我有一个ViewModel,它绑定到View(作为DataContext)。

public class UserViewModel : INotifyPropertyChanged
{
    // Interface for PropertyChanged is implemented, I will not post this code here ...

    // This should be set, when any textbox/control is changed in the detail
    public boolean DataChanged { get; set; }

    private User _user;
    public User Data {
        get { return this._user; }
        set
        {
            if(value != _user) {                
               this._user = value;
               this.RaisePropertyChangedEvent("Data");
            }
        }
    }
}

在视图中,详细控件的定义如下

<local:UserDetailControl 
        x:Name="userDetailControl"
        DataContext="{Binding Path=Data, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
</local:UserDetailControl>

详细控件的DataContext绑定设置为ViewModel的Data属性。 这样工作正常,文本框将填充正确的数据。

详细控制UC示例:

<TextBox x:Name="idTextBox" Text="{Binding Path=ID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=PropertyChanged}"/>

我想要的是:如果在详细信息UC中更改了任何控件(文本框),则应更改ViewModel属性DataChanged(为true)。

我试过跟......

1)向详细用户控件添加了INotifyPropertyChanged,为ID添加了一个属性,但不会调用setter / getter,因为Binding对象是DataContext。

2)为ID添加了DependencyProperty并提升了PropertyChanged

public string ID
{
    get { return (string)GetValue(IDProperty); }
    set { SetValue(IDProperty, value); }
}

public static readonly DependencyProperty IDProperty =
        DependencyProperty.Register("ID", typeof(string), typeof(UserDetailControl), new FrameworkPropertyMetadata(OnIDChanged));

private static void OnIDChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    UserDetailControl control = obj as UserDetailControl;
    control.RaisePropertyChangedEvent("ID");
}

但这绝不会被称为......

3)为(每个)文本框添加TextChanged事件并引发PropertyChanged事件。 (这很有效,但我认为并不优雅)

4)我正在考虑将DataChanged属性绑定到详细的​​UC,但这不会解决我的问题...它只是一个更好的方式,我可以处理详细UC中的状态。

那么,是否有任何其他想法/解决方案/建议如何以简单的方式解决我的问题?谢谢你们,伙计们!

更新/解决方案

向Detail UserControl添加了一个新的依赖项属性Data,并将TextBox属性设置为此Data.ID

    public User Data
    {
        get
        {
            return (User)GetValue(DataProperty);
        }
        set
        {
            SetValue(DataProperty, value);
        }
    }


    public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(User), typeof(UserDetailControl), new FrameworkPropertyMetadata(OnDataChanged));


    private static void OnDataChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {

        UserDetailControl control = obj as UserDetailControl;
        control.RaisePropertyChangedEvent("ID");
    }

然后我不得不修改我的Detail UC XAML代码:

 <UserControl ... x:Name="root">
      <Grid Margin="0,0,0,-193" DataContext="{Binding ElementName=root}">
 </UserControl>

(见:http://blog.scottlogic.com/2012/02/06/a-simple-pattern-for-creating-re-useable-usercontrols-in-wpf-silverlight.html

0 个答案:

没有答案