2017-09-11 46 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