2016-12-05 70 views
1

我設置了兩個取消對方的複選框。檢測RxUI中的循環引用

,我想看到的行爲是一個infintite環(複選框1個檢查2檢查1個檢查2 ...)

而是改變的傳播是其他其他複選框後停止由RxUI檢查。

是否有某種檢測到循環引用內置到RxUI中?

using ReactiveUI; 
using ReactiveUI.Fody.Helpers; 
using System; 

namespace rxnested 
{ 
    public class VM01 : ReactiveObject 
    { 
     [Reactive] 
     public bool Prop1 { get; set; } 

     [Reactive] 
     public bool Prop2 { get; set; } 

     public VM01() 
     { 
      this.WhenAnyValue(x => x.Prop1) 
       .Subscribe(x => Prop2 = !x); 


      this.WhenAnyValue(x => x.Prop2) 
       .Subscribe(x => Prop1 = !x); 
     } 
    } 
} 

<Window x:Class="rxnested.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:rxnested" 
     mc:Ignorable="d" 
     Title="MainWindow" 
     Height="350" 
     Width="525"> 
    <Window.DataContext> 
     <local:VM01></local:VM01> 
    </Window.DataContext> 
    <StackPanel> 
     <CheckBox IsChecked="{Binding Prop1}"></CheckBox> 
     <CheckBox IsChecked="{Binding Prop2}"></CheckBox> 
    </StackPanel> 
</Window> 
+0

我希望不要懷疑它。海事組織它會放慢框架。在這種情況下,程序員的工作不是創建不同類型的無限循環。 – kenny

回答

2

我認爲你的期望,你的代碼應該導致無限循環是錯誤的。

有兩種情況。讓我們分開考慮它們。

1)假設最初兩個屬性具有相同的值(假設它是假的)。將P1更改爲true會觸發第一次訂閱,它將嘗試將P2設置爲P1的當前值(反向true == false)的相反值。這意味着它會嘗試將錯誤設置爲已經錯誤的東西,因此什麼都不會發生(這就是[Reactive]給你的東西 - 在設置屬性之前,它會檢查它是否已經改變)。

2)現在P1最初是真的,P2是假的。將P1更改爲false會觸發第一次訂閱,即將P2設置爲(!P1),在此情況下爲true。所以,P2從假變爲真。這會觸發第二次訂閱,它會嘗試將P1設置爲(!P2),現在它是錯誤的。但P1已經是假的,所以屬性不會改變(因此NotifyPropertyChanged不會觸發)。

所以,週期是由不凝性盲目,但首先檢查它是否改變了所有(以避免不必要的NotifyPropertyChanged事件)打破。

當你意識到[Reactive]轉換成這更是明確:

private bool _prop2; 
    public bool Prop2 
    { 
     get { return _prop2; } 
     set { this.RaiseAndSetIfChanged(ref _prop2, value); } 
    } 

註名 - RaiseAndSet IfChanged。現在

,如果你想看到一個無限循環..簡單地改變你的代碼如下:

public VM01() 
    { 
     this.WhenAnyValue(x => x.Prop1) 
      .Subscribe(x => Prop2 = !Prop2); 


     this.WhenAnyValue(x => x.Prop2) 
      .Subscribe(x => Prop1 = !Prop1); 
    } 

這給了我StackOverflowException