c# – 如何将ReactiveUI与分层数据源一起使用(树视图)
我已经找到了一种通过ReactiveUI动态绑定树视图中的用户控件的方法.
但…… 所以,我的问题是:我是否遗漏了ReactiveUI框架中的一些东西,让我绑定this.OneWayBind并将HierachicalDataTemplete移动到后面的代码或自定义用户控件? 特别是 – OneWayBind是否有另一个支持分层数据模板的重载,或者在使用时抑制数据模板生成的方法? 更新 以下是关键细节: 主视图中的树控制 <TreeView Name="FamilyTree" > <TreeView.Resources> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsSelected" Value="{Binding IsSelected,Mode=TwoWay}"/> <Setter Property="IsExpanded" Value="{Binding IsExpanded,Mode=TwoWay}"/> </Style> <HierarchicalDataTemplate DataType="{x:Type local:TreeItem}" ItemsSource="{Binding Children}"> <reactiveUi:ViewModelViewHost ViewModel="{Binding ViewModel}"/> </HierarchicalDataTemplate> </TreeView.Resources> </TreeView> 主视图代码背后 public partial class MainWindow : Window,IViewFor<MainVM> { public MainWindow() { InitializeComponent(); //build viewmodel ViewModel = new MainVM(); //Register views Locator.CurrentMutable.Register(() => new PersonView(),typeof(IViewFor<Person>)); Locator.CurrentMutable.Register(() => new PetView(),typeof(IViewFor<Pet>)); //NB. ! Do not use 'this.OneWayBind ... ' for the top level binding to the tree view //this.OneWayBind(ViewModel,vm => vm.Family,v => v.FamilyTree.ItemsSource); FamilyTree.ItemsSource = ViewModel.Family; } ... } MainViewModel public class MainVM : ReactiveObject { public MainVM() { var bobbyJoe = new Person("Bobby Joe",new[] { new Pet("Fluffy") }); var bob = new Person("Bob",new[] { bobbyJoe }); var littleJoe = new Person("Little Joe"); var joe = new Person("Joe",new[] { littleJoe }); Family = new ReactiveList<TreeItem> { bob,joe }; _addPerson = ReactiveCommand.Create(); _addPerson.Subscribe(_ => { if (SelectedItem == null) return; var p = new Person(NewName); SelectedItem.AddChild(p); p.IsSelected = true; p.ExpandPath(); }); } public ReactiveList<TreeItem> Family { get; } ... } TreeItem基类 public abstract class TreeItem : ReactiveObject { private readonly Type _viewModelType; bool _isExpanded; public bool IsExpanded { get { return _isExpanded; } set { this.RaiseAndSetIfChanged(ref _isExpanded,value); } } bool _isSelected; public bool IsSelected { get { return _isSelected; } set { this.RaiseAndSetIfChanged(ref _isSelected,value); } } private TreeItem _parent; protected TreeItem(IEnumerable<TreeItem> children = null) { Children = new ReactiveList<TreeItem>(); if (children == null) return; foreach (var child in children) { AddChild(child); } } public abstract object ViewModel { get; } public ReactiveList<TreeItem> Children { get; } public void AddChild(TreeItem child) { child._parent = this; Children.Add(child); } public void ExpandPath() { IsExpanded = true; _parent?.ExpandPath(); } public void CollapsePath() { IsExpanded = false; _parent?.CollapsePath(); } } 人类 public class Person : TreeItem { public string Name { get; set; } public Person(string name,IEnumerable<TreeItem> children = null) : base(children) { Name = name; } public override object ViewModel => this; } 人查看用户控件 <UserControl x:Class="TreeViewInheritedItem.PersonView"... > <StackPanel> <TextBlock Name="PersonName"/> </StackPanel> </UserControl> 人视图代码背后 public partial class PersonView : UserControl,IViewFor<Person> { public PersonView() { InitializeComponent(); this.OneWayBind(ViewModel,vm => vm.Name,v => v.PersonName.Text); } ... } 宠物的工作和人一样. 整个项目在这里ReactiveUI Tree view Sample 解决方法
我查看了ReactiveUI源代码,这是执行此操作的唯一方法.绑定帮助器方法始终使用DataTemplate而不是HierarchicalDataTemplate.
因此,此方法将使用XAML绑定进行最高级别,然后让您在所有TreeView项目上使用ReactiveUI绑定. 我将看到创建一个拉请求来处理这个边缘情况. 谢谢,??克里斯 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |