/// <summary> /// Indicates that a property change should cause <see cref="InvalidateVisual"/> to be /// called. /// </summary> /// <typeparam name="T">The control which the property affects.</typeparam> /// <param name="properties">The properties.</param> /// <remarks> /// This method should be called in a control's static constructor with each property /// on the control which when changed should cause a redraw. This is similar to WPF's /// FrameworkPropertyMetadata.AffectsRender flag. /// </remarks> protected static void AffectsRender <T>(params AvaloniaProperty[] properties) where T : Visual { void Invalidate(AvaloniaPropertyChangedEventArgs e) { if (e.Sender is T sender) { if (e.OldValue is IAffectsRender oldValue) { WeakEventHandlerManager.Unsubscribe <EventArgs, T>(oldValue, nameof(oldValue.Invalidated), sender.AffectsRenderInvalidated); } if (e.NewValue is IAffectsRender newValue) { WeakEventHandlerManager.Subscribe <IAffectsRender, EventArgs, T>(newValue, nameof(newValue.Invalidated), sender.AffectsRenderInvalidated); } sender.InvalidateVisual(); } } foreach (var property in properties) { property.Changed.Subscribe(Invalidate); } }
protected override void UnsubscribeCore() { if (_reference.TryGetTarget(out var o) && o is INotifyPropertyChanged inpc) { WeakEventHandlerManager.Unsubscribe <PropertyChangedEventArgs, InpcPropertyAccessor>( inpc, nameof(INotifyPropertyChanged.PropertyChanged), OnNotifyPropertyChanged); } }
protected override void UnsubscribeCore() { base.UnsubscribeCore(); if (_reference.TryGetTarget(out var o) && o is INotifyCollectionChanged incc) { WeakEventHandlerManager.Unsubscribe <NotifyCollectionChangedEventArgs, IndexerAccessor>( incc, nameof(INotifyCollectionChanged.CollectionChanged), OnNotifyCollectionChanged); } }
public void EventShouldNotBeRaisedAfterUnsubscribe() { bool handled = false; var subscriber = new Subscriber(() => handled = true); var source = new EventSource(); WeakEventHandlerManager.Subscribe <EventSource, EventArgs, Subscriber>(source, "Event", subscriber.OnEvent); WeakEventHandlerManager.Unsubscribe <EventArgs, Subscriber>(source, "Event", subscriber.OnEvent); source.Fire(); Assert.False(handled); }
static void InvalidateAndSubscribe(AvaloniaPropertyChangedEventArgs e) { if (e.Sender is T sender) { if (e.OldValue is IAffectsRender oldValue) { WeakEventHandlerManager.Unsubscribe <EventArgs, T>(oldValue, nameof(oldValue.Invalidated), sender.AffectsRenderInvalidated); } if (e.NewValue is IAffectsRender newValue) { WeakEventHandlerManager.Subscribe <IAffectsRender, EventArgs, T>(newValue, nameof(newValue.Invalidated), sender.AffectsRenderInvalidated); } sender.InvalidateVisual(); } }