在ReactiveUI 9中,不推荐使用ReactiveList
来支持DynamicData(Blog post)。我目前正在尝试更新代码以使用SourceList
。我能够使ViewModel正常工作,但是在WPF中使用SourceList
作为绑定数据源似乎并不容易。
我的第一个尝试是创建绑定,就像在以前版本的ReactiveUI中一样:
this.OneWayBind(ViewModel, vm => vm.MyList, v => v.MyListView.ItemsSource);
这不起作用,因为SourceList
不可枚举(无法将DynamicData.ISourceList转换为System.Collections.IEnumerable)
我的第二次尝试是使用列表的Items
属性。
this.OneWayBind(ViewModel, vm => vm.MyList.Items, v => v.MyListView.ItemsSource);
这不起作用,因为Items
获取器在内部创建列表的副本,这意味着列表中的更改不会反映在视图中。
我的第三次尝试是使用Bind
方法创建一个ReadOnlyObservableCollection
。
我不想在viewmodel中执行此操作,因为那样的话,我将不得不为每个viewmodel中的每个列表添加第二个list属性,这会使我的代码混乱,这违反了DRY原理。此外,要绑定到的列表的类型取决于所使用的视图框架。 (例如:WinForms改用BindingList
)
此外,我的视图的视图模型可能会更改,这意味着在设置新的视图模型时,必须清理并替换生成的绑定和列表。这给出了以下代码片段:
this.WhenAnyValue(v => v.ViewModel.VisibleInputs)
.Select(l =>
{
var disposer = l.Connect().Bind(out var list).Subscribe();
return (List: list, Disposer: disposer);
})
.PairWithPreviousValue()
.Do(p => p.OldValue.Disposer?.Dispose()) // Cleanup the previous list binding
.Select(p => p.NewValue.List)
.BindTo(this, v => v.InputsList.ItemsSource);
这很好用,但是很冗长。我可以为此创建扩展方法,但是也许有更好/内置的方法可以与DynamicData进行WPF列表绑定?
答案 0 :(得分:1)
我认为这样的想法是,视图绑定到调度程序线程上的IObservableCollection<T>
,并且SourceList<T>
用流生成的对象来馈送该视图,例如:
public class MainViewModel : ReactiveObject
{
private SourceList<int> _myList { get; } = new SourceList<int>();
private readonly IObservableCollection<int> _targetCollection = new ObservableCollectionExtended<int>();
public MainViewModel()
{
Task.Run(()=>
{
for (int i = 0; i < 100; ++i)
{
_myList.Add(i);
System.Threading.Thread.Sleep(500);
}
});
_myList.Connect()
.ObserveOnDispatcher()
.Bind(_targetCollection)
.Subscribe();
}
public IObservableCollection<int> TargetCollection => _targetCollection;
}
查看:
this.OneWayBind(ViewModel, vm => vm.TargetCollection, v => v.MyListView.ItemsSource);
您可以了解有关此here的更多信息。