/// <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); } }
public void Test1() { WeakEventHandlerManager manager = new WeakEventHandlerManager(); int[] eventCount_delegate = new int[1]; EventHandler_v2 <ListEventArgs> count_delegate = (sender, args) => { eventCount_delegate[0]++; }; DisposableCounter disposable = new DisposableCounter(); manager.For <EventList <int> >().RegisterWeak("Count_delegate", count_delegate, (x, h) => x.ListChanged += h, (x, h) => x.ListChanged -= h); manager.For <EventList <int> >().RegisterWeak <ListEventArgs>("Count_static", Count_static, (x, h) => x.ListChanged += h, (x, h) => x.ListChanged -= h); manager.For <EventList <int> >().RegisterWeak <ListEventArgs>("Count_instance", this.Count_instance, (x, h) => x.ListChanged += h, (x, h) => x.ListChanged -= h); manager.For <EventList <int> >().RegisterWeak <ListEventArgs>("Count_disposable", disposable.Count, (x, h) => x.ListChanged += h, (x, h) => x.ListChanged -= h); { eventCount_delegate[0] = 0; this.eventCount_instance = 0; eventCount_static = 0; EventList <int> eventList = new EventList <int>(); manager.AddWeak("Count_delegate", eventList); manager.AddWeak("Count_static", eventList); manager.AddWeak("Count_instance", eventList); manager.AddWeak("Count_disposable", eventList); eventList.Add(0); eventList.Add(5); eventList.Add(10); eventList.Add(15); eventList.Add(20); eventList = null; GC.Collect(); GC.WaitForPendingFinalizers(); Debug.WriteLine("eventCount_delegate = " + eventCount_delegate[0]); Debug.WriteLine("eventCount_static = " + eventCount_static); Debug.WriteLine("eventCount_instance = " + this.eventCount_instance); Debug.WriteLine("eventCount_disposable = " + disposable.eventCount_disposable); } manager.RemoveWeak("ListChanged"); }
void ConnectAnchor(ITypeDescriptorContext context) { // This is a horrible hack to have the control keep the binding alive. var window = context.GetFirstParent <Window>(); _anchor.Tag = this; WeakEventHandlerManager.Subscribe <Window, EventArgs, LocalizedResourceExtension>(window, nameof(Window.Closed), DisconnectAnchor); }
private void SubscribeToChanges() { if (_reference.TryGetTarget(out var o) && o is INotifyPropertyChanged inpc) { WeakEventHandlerManager.Subscribe <INotifyPropertyChanged, PropertyChangedEventArgs, InpcPropertyAccessor>( inpc, nameof(INotifyPropertyChanged.PropertyChanged), OnNotifyPropertyChanged); } }
protected override void UnsubscribeCore() { if (_reference.TryGetTarget(out var o) && o is INotifyPropertyChanged inpc) { WeakEventHandlerManager.Unsubscribe <PropertyChangedEventArgs, InpcPropertyAccessor>( inpc, nameof(INotifyPropertyChanged.PropertyChanged), OnNotifyPropertyChanged); } }
private void SubscribeToApplicationEvents() { WeakEventHandlerManager.Subscribe <ClientApplication, ConnectionStateChangedEventArgs, MainViewModel>( Application.Instance, nameof(Application.Instance.ConnectionStateChanged), OnConnectionStateChanged); WeakEventHandlerManager.Subscribe <ClientApplication, ReconnectionTimeChangedEventArgs, MainViewModel>( Application.Instance, nameof(Application.Instance.ReconnectionTimeChanged), OnReconnectionTimeChanged); IsConnected = Application.Instance.IsConnected; ReconnectionTime = Application.Instance.ReconnectionTime; }
public void EventShouldBePassedToSubscriber() { bool handled = false; var subscriber = new Subscriber(() => handled = true); var source = new EventSource(); WeakEventHandlerManager.Subscribe <EventSource, EventArgs, Subscriber>(source, "Event", subscriber.OnEvent); source.Fire(); Assert.True(handled); }
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(); } }
private void AddCollectableSubscriber(EventSource source, string name, Action func) { WeakEventHandlerManager.Subscribe <EventSource, EventArgs, Subscriber>(source, name, new Subscriber(func).OnEvent); }
private void Subscribe(Window window) { WeakEventHandlerManager.Subscribe <Window, EventArgs, LocalizedResourceExtension>(window, nameof(Window.Closed), DisconnectAnchor); }
/// <summary> /// Raises <see cref="ICommand.CanExecuteChanged"/> on the UI thread so every /// command invoker can requery <see cref="ICommand.CanExecute"/> to check if the /// <see cref="CompositeCommand"/> can execute. /// </summary> protected virtual void OnCanExecuteChanged() { WeakEventHandlerManager.CallWeakReferenceHandlers(this, _canExecuteChangedHandlers); }
///<summary> /// Invokes the <see cref="CanExecuteChanged"/> event. ///</summary> public void OnCanExecuteChanged() { WeakEventHandlerManager.CallWeakReferenceHandlers(this, _canExecuteChangedHandlers); }
protected virtual void OnCanExecuteChanged() { CommandManager.InvalidateRequerySuggested(); WeakEventHandlerManager.CallWeakReferenceHandlers(this, _canExecuteChangedHandlers); }