假设视图模型正确实现INotifyPropertyChanged
,对后面代码中视图模型(未指定类型)的属性名为 foo 的更改做出反应的最佳方法是什么? ?
通常可以绑定控件元素来查看模型属性,一切正常。但在这种情况下,这还不够,我需要在属性更改时执行一些c#行。
可以监听DataContext的相应事件,但是,我还处理了DataContext本身的更改。另一种可能的解决方案是在代码隐藏文件中引入DependencyProperty
。但是,有没有更短的方式?
答案 0 :(得分:12)
我建议尽可能避免这种情况。如果有必要,请订阅INotifyPropertyChanged viewModel = (INotifyPropertyChanged)this.DataContext;
viewModel.PropertyChanged += (sender, args) => {
if (!args.PropertyName.Equals("foo"))
return;
// execute code here.
};
事件。
我会将此代码放在代码隐藏构造函数中。
nameof
可维护性提示如果您确定数据上下文是具有该属性的类型,则转换为该类型并使用INotifyPropertyChanged previous;
// constructor
public SomeCodeBehindClass()
{
previous = (INotifyPropertyChanged)this.DataContext;
DataContextChanged += (sender, args) => SubscribeToFooChanges((INotifyPropertyChanged)args.NewValue);
SubscribeToFooChanges(previous);
}
// subscriber
private void SubscribeToFooChanges(INotifyPropertyChanged viewModel)
{
if (previous != null)
previous.PropertyChanged -= FooChanged;
previous = viewModel;
if (viewModel != null)
viewModel.PropertyChanged += FooChanged;
}
// event handler
private void FooChanged (object sender, PropertyChangedEventArgs args)
{
if (!args.PropertyName.Equals("foo"))
return;
// execute code here.
}
运算符而不是魔术字符串。
编辑(对datacontext更改做出反应)
您应该能够订阅DataContextChanged事件来处理数据上下文中的更改。
LiftRules.dispatch.prepend {
case Req("toolsearch" :: Nil, _, _) =>{
() => Full(RedirectResponse("/search"))
}
}
答案 1 :(得分:1)
可能的解决方案,在你背后的代码中你可以做到这一点
(((dynamic)DataContext).foo as ObservableCollection<object>).CollectionChanged += (s, e) =>
{
if (e.Action == NotifyCollectionChangedAction.Replace)
{
}
else
{
//and so on
}
};
答案 2 :(得分:-1)
如果这些代码行与业务逻辑相关,则不应在后面的代码中使用它们。 在其他情况下,视图模型的属性将始终绑定到任何标记元素,如果必须以某种方式预处理此属性值,则应使用转换器