using Avalonia; using ReactiveUI; using Ursa.Controls; /* These codes are ported from ReactiveUI.Avalonia. * **/ namespace Ursa.ReactiveUIExtension; /// /// A ReactiveUI that implements the interface and /// will activate your ViewModel automatically if the view model implements . /// When the DataContext property changes, this class will update the ViewModel property with the new DataContext /// value, and vice versa. /// /// ViewModel type. public class ReactiveUrsaView : UrsaView, IViewFor where TViewModel : class { [System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1002", Justification = "Generic avalonia property is expected here.")] public static readonly StyledProperty ViewModelProperty = AvaloniaProperty .Register, TViewModel?>(nameof(ViewModel)); /// /// Initializes a new instance of the class. /// public ReactiveUrsaView() { // This WhenActivated block calls ViewModel's WhenActivated // block if the ViewModel implements IActivatableViewModel. this.WhenActivated(disposables => { }); } /// /// The ViewModel. /// public TViewModel? ViewModel { get => GetValue(ViewModelProperty); set => SetValue(ViewModelProperty, value); } object? IViewFor.ViewModel { get => ViewModel; set => ViewModel = (TViewModel?)value; } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); if (change.Property == DataContextProperty) { if (ReferenceEquals(change.OldValue, ViewModel) && change.NewValue is null or TViewModel) { SetCurrentValue(ViewModelProperty, change.NewValue); } } else if (change.Property == ViewModelProperty) { if (ReferenceEquals(change.OldValue, DataContext)) { SetCurrentValue(DataContextProperty, change.NewValue); } } } }