Skip to content

Commit

Permalink
Use soft DataContext synchronization for Reactive UI controls. (#14477)
Browse files Browse the repository at this point in the history
  • Loading branch information
jp2masa authored Feb 4, 2024
1 parent 942901c commit 0e9ce15
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 37 deletions.
27 changes: 12 additions & 15 deletions src/Avalonia.ReactiveUI/ReactiveUserControl.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
using ReactiveUI;

Expand All @@ -29,7 +25,6 @@ public ReactiveUserControl()
// This WhenActivated block calls ViewModel's WhenActivated
// block if the ViewModel implements IActivatableViewModel.
this.WhenActivated(disposables => { });
this.GetObservable(ViewModelProperty).Subscribe(OnViewModelChanged);
}

/// <summary>
Expand All @@ -47,21 +42,23 @@ public TViewModel? ViewModel
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);
}
}
}
}
Expand Down
34 changes: 12 additions & 22 deletions src/Avalonia.ReactiveUI/ReactiveWindow.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
using ReactiveUI;

Expand All @@ -29,8 +25,6 @@ public ReactiveWindow()
// 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>
Expand All @@ -48,27 +42,23 @@ public TViewModel? ViewModel
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);
}
}
}
}
Expand Down

0 comments on commit 0e9ce15

Please sign in to comment.