Browse Source

Use soft DataContext synchronization for Reactive UI controls. (#14477)

pull/14481/head
jp2masa 3 years ago
committed by GitHub
parent
commit
0e9ce15223
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 27
      src/Avalonia.ReactiveUI/ReactiveUserControl.cs
  2. 34
      src/Avalonia.ReactiveUI/ReactiveWindow.cs

27
src/Avalonia.ReactiveUI/ReactiveUserControl.cs

@ -1,8 +1,4 @@
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
using ReactiveUI;
@ -29,7 +25,6 @@ namespace Avalonia.ReactiveUI
// This WhenActivated block calls ViewModel's WhenActivated
// block if the ViewModel implements IActivatableViewModel.
this.WhenActivated(disposables => { });
this.GetObservable(ViewModelProperty).Subscribe(OnViewModelChanged);
}
/// <summary>
@ -47,21 +42,23 @@ namespace Avalonia.ReactiveUI
set => ViewModel = (TViewModel?)value;
}
protected override void OnDataContextChanged(EventArgs e)
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnDataContextChanged(e);
ViewModel = DataContext as TViewModel;
}
base.OnPropertyChanged(change);
private void OnViewModelChanged(object? value)
{
if (value == null)
if (change.Property == DataContextProperty)
{
ClearValue(DataContextProperty);
if (Object.ReferenceEquals(change.OldValue, ViewModel))
{
SetCurrentValue(ViewModelProperty, change.NewValue);
}
}
else if (DataContext != value)
else if (change.Property == ViewModelProperty)
{
DataContext = value;
if (Object.ReferenceEquals(change.OldValue, DataContext))
{
SetCurrentValue(DataContextProperty, change.NewValue);
}
}
}
}

34
src/Avalonia.ReactiveUI/ReactiveWindow.cs

@ -1,8 +1,4 @@
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
using ReactiveUI;
@ -29,8 +25,6 @@ namespace Avalonia.ReactiveUI
// This WhenActivated block calls ViewModel's WhenActivated
// block if the ViewModel implements IActivatableViewModel.
this.WhenActivated(disposables => { });
this.GetObservable(DataContextProperty).Subscribe(OnDataContextChanged);
this.GetObservable(ViewModelProperty).Subscribe(OnViewModelChanged);
}
/// <summary>
@ -48,27 +42,23 @@ namespace Avalonia.ReactiveUI
set => ViewModel = (TViewModel?)value;
}
private void OnDataContextChanged(object? value)
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
if (value is TViewModel viewModel)
{
ViewModel = viewModel;
}
else
{
ViewModel = null;
}
}
base.OnPropertyChanged(change);
private void OnViewModelChanged(object? value)
{
if (value == null)
if (change.Property == DataContextProperty)
{
ClearValue(DataContextProperty);
if (Object.ReferenceEquals(change.OldValue, ViewModel))
{
SetCurrentValue(ViewModelProperty, change.NewValue);
}
}
else if (DataContext != value)
else if (change.Property == ViewModelProperty)
{
DataContext = value;
if (Object.ReferenceEquals(change.OldValue, DataContext))
{
SetCurrentValue(DataContextProperty, change.NewValue);
}
}
}
}

Loading…
Cancel
Save