有没有办法直接绑定(bind)到模型中的集合并手动告诉 WPF 绑定(bind)需要刷新,而不必在 View 模型中为其创建 ObservableCollection?
<ListBox ItemsSource="{Binding Position.PossibleMoves}">
...
</ListBox>
Position 是我的模型,是国际象棋库的一部分,PossibleMoves 是其中的一个集合。我不想实现 INotifyProperty 更改或将 ObservableCollections 放在独立的优化库中。
我想避免在每次更新位置时将 PossibleMoves 复制到 ObservableCollection 中。数据绑定(bind)在初始化时起作用,但如果我也可以在 View 模型中随意刷新绑定(bind),那将很方便。
从 View 模型调用 OnNotifyPropertyChanged("Position.PossibleMoves") 不起作用,因为对集合本身的引用不会改变。
最佳答案
您可以通过使用附加行为将处理程序绑定(bind)到在 View 模型中触发的事件来做到这一点。你不能直接绑定(bind)到事件,所以你必须将它们包装在一个类中,如下所示:
public class Refresher
{
public delegate void RefreshDelegate();
public event RefreshDelegate Refresh;
public void DoRefresh()
{
if (this.Refresh != null)
this.Refresh();
}
}
现在将它的一个实例添加到您的 View 模型中:
public class MyViewModel
{
public IList<string> Items { get; set; }
private Refresher _Refresher = new Refresher();
public Refresher Refresher {get {return this._Refresher;}}
}
接下来创建一个附加行为,向该事件注册一个委托(delegate)实例并强制列表框刷新其绑定(bind):
public static class RefreshBehavior
{
public static readonly DependencyProperty RefresherProperty = DependencyProperty.RegisterAttached(
"Refresher",
typeof(Refresher),
typeof(RefreshBehavior),
new PropertyMetadata(null, OnRefresherChange));
public static void SetRefresher(DependencyObject source, Refresher value)
{
source.SetValue(RefresherProperty, value);
}
public static Refresher GetRefresher(DependencyObject source)
{
return (Refresher)source.GetValue(RefresherProperty);
}
private static void OnRefresherChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Refresher.RefreshDelegate handler = () =>
{
var listBox = d as ListBox;
listBox.Items.Refresh();
};
if (e.NewValue != null)
(e.NewValue as Refresher).Refresh += handler;
if (e.OldValue != null)
(e.OldValue as Refresher).Refresh -= handler;
}
}
最后将其附加到 xaml 中的列表框:
<ListBox ItemsSource="{Binding Items}"
local:RefreshBehavior.Refresher="{Binding Refresher}"/>
就是这样。调用
Refresher.DoRefresh()
在您的 View 模型中,它将强制更新列表框。这行得通,但它实际上是将一个方形钉子锤入一个圆孔。如果我是你,我会尽我所能尝试在你的 View 模型中做正确的集合更改通知。我了解您希望将 ObservableCollection 排除在模型之外,但有一些方法可以自动代理更改通知(例如 CaSTLe DynamicProxy)。
关于wpf - 如何绑定(bind)到非 ObservableCollection?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21491420/