我已经找到了一种通过ReactiveUI动态绑定树视图中的用户控件的方法.
但……
对HierachicalDataSource的顶级绑定是在XAML中而不是后面的代码,我需要直接设置ItemsSource,而不是根据ReactiveUI绑定的一般模式使用this.OneWayBind.
所以,我的问题是:我是否遗漏了ReactiveUI框架中的一些东西,让我绑定this.OneWayBind并将HierachicalDataTemplete移动到后面的代码或自定义用户控件?
特别是 – OneWayBind是否有另一个支持分层数据模板的重载,或者在使用时抑制数据模板生成的方法?
更新
我已经为我的测试项目添加了所选项目和Expand和Selected的编程支持,但我不得不为XAML添加一个样式.我想用一个简单的RxUI Bind替换它.更新了示例.
以下是关键细节:
主视图中的树控制
<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); } ... }
宠物的工作和人一样.
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。