2017-09-11 45 views
1

如何观察树的任何子层的属性更改?在Rx.NET中使用树/ ReactiveUI

考虑例如具有属性NameChildNodes的属性TreeNode。如何观察Name任何子级的变化TreeNode

的使用可能是这个样子:

rootNode.FlattenTreeToObservable(x => x.ChildNodes) 
     .WhenAnyValue(x => x.Name) 
     .Subscribe(...) 

树节点例如:

// NuGet: Install-Package reactiveui 
// In case of Splat version issue: Install-Package Splat -Version 1.6.2 
using ReactiveUI; 

public class TreeNode: ReactiveObject 
{ 
    public string Name 
    { 
     get { return this._name; } 
     set { this.RaiseAndSetIfChanged(ref this._name, value); } 
    } 
    private string _name = ""; 

    public ReactiveList<TreeNode> ChildNodes 
    { 
     get { return this._childNodes; } 
     set { this.RaiseAndSetIfChanged(ref this._childNodes, value); } 
    } 
    private ReactiveList<TreeNode> _childNodes = new ReactiveList<TreeNode>(); 
} 
+0

请提供TreeNode'的'满级定义以及任何支持类。你应该尽可能简单地让我们回答。 – Enigmativity

+1

他们完全对我很重要。如果你能提供具体的课程,那么你会让人们回答。否则,你要求我们设计一个系统。这在艰苦工作中太过分了。就像我说过的,你应该尽可能简单地让我们回答。 – Enigmativity

+0

什么是RaiseAndSetIfChanged?我试图复制,粘贴和编译你的代码。 – Enigmativity

回答

1

我不能让你的代码运行 - 我结束了一个DLL版本问题,所以我写了使用相同的结构,你的基本类得到这个工作:

public class TreeNode 
{ 
    public string Name { get; set; } 

    public Subject<TreeNode> ChildNodes { get; } 
     = new Subject<TreeNode>(); 
} 

我接着又说了FOL降脂方法:

public IObservable<TreeNode> FlattenTreeToObservable() 
    { 
     return 
      this.ChildNodes 
       .SelectMany(cn => cn.FlattenTreeToObservable()) 
       .StartWith(this); 
    } 

现在,当我运行这个测试代码:

var root = new TreeNode() { Name = "R" }; 

root.FlattenTreeToObservable().Subscribe(tn => Console.WriteLine(tn.Name)); 

var a1 = new TreeNode() { Name = "A1" }; 
root.ChildNodes.OnNext(a1); 

var b11 = new TreeNode() { Name = "B11" }; 
a1.ChildNodes.OnNext(b11); 

var b12 = new TreeNode() { Name = "B12" }; 
a1.ChildNodes.OnNext(b12); 

var a2 = new TreeNode() { Name = "A2" }; 
root.ChildNodes.OnNext(a2); 

var b21 = new TreeNode() { Name = "B21" }; 
a2.ChildNodes.OnNext(b21); 

var b22 = new TreeNode() { Name = "B22" }; 
a2.ChildNodes.OnNext(b22); 

我得到这样的输出:

 
R 
A1 
B11 
B12 
A2 
B21 
B22 
+0

这看起来不错!我想知道当你做一些类似'a1.ChildNodes = ...'的事情时它是否会中断。现在不能测试,但会回来给你。 – John

+0

至于DLL版本问题,请参阅示例中关于'Splat'的注释。 – John

+0

@John - 不,不要做'a1.ChildNodes = ...'。这会杀死它。 – Enigmativity