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