2016-12-05 65 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