在 Rx.NET / ReactiveUI 中使用树
Working with Trees in Rx.NET / ReactiveUI
如何观察 属性 树的任何子级别的变化?
例如,考虑具有属性 Name
和 ChildNodes
的 class TreeNode
。如何在 TreeNode
的任何子级别观察 Name
变化?
用法可能如下所示:
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>();
}
我无法将您的代码获取到 运行 - 我最终遇到了 DLL 版本控制问题,因此我编写了一个基本的 class,它使用与您的相同的结构来使其工作:
public class TreeNode
{
public string Name { get; set; }
public Subject<TreeNode> ChildNodes { get; }
= new Subject<TreeNode>();
}
然后我添加了以下方法:
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
如何观察 属性 树的任何子级别的变化?
例如,考虑具有属性 Name
和 ChildNodes
的 class TreeNode
。如何在 TreeNode
的任何子级别观察 Name
变化?
用法可能如下所示:
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>();
}
我无法将您的代码获取到 运行 - 我最终遇到了 DLL 版本控制问题,因此我编写了一个基本的 class,它使用与您的相同的结构来使其工作:
public class TreeNode
{
public string Name { get; set; }
public Subject<TreeNode> ChildNodes { get; }
= new Subject<TreeNode>();
}
然后我添加了以下方法:
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