public void BasicConstructorLifeCycleTest() { var listenerSuccess = false; var publisher = new TestEventPublisher(); var listener = new PropertyChangedWeakEventListener(publisher, (sender, e) => listenerSuccess = true); //------------------ listenerSuccess.Is(false); publisher.RaisePropertyChanged(string.Empty); listenerSuccess.Is(true); //------------------ listenerSuccess = false; listener.Dispose(); publisher.RaisePropertyChanged(string.Empty); listenerSuccess.Is(false); try { listener.RegisterHandler((sender, e) => listenerSuccess = true); } catch (Exception e) { e.GetType().Is(typeof(ObjectDisposedException)); } }
public void WeakEventTest() { var listener1Success = false; var eventPublisher = new TestEventPublisher(); var listener1 = new PropertyChangedWeakEventListener(eventPublisher, (sender, e) => listener1Success = true); var listenerWeakReference = new WeakReference(listener1); //------------------ listener1Success.Is(false); eventPublisher.RaisePropertyChanged(null); listener1Success.Is(true); //------------------ listener1Success = false; listener1 = null; GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); eventPublisher.RaisePropertyChanged(null); listener1Success.Is(false); }
public void SourceReferenceMemoryLeakTest() { var handler1Called = false; var publisherStrongReference = new TestEventPublisher(); var publisherWeakReference = new WeakReference <TestEventPublisher>(publisherStrongReference); var listener = new PropertyChangedWeakEventListener(publisherStrongReference); listener.RegisterHandler("Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler1Called = true; }); publisherStrongReference.RaisePropertyChanged("Dummy1"); handler1Called.Is(true); listener.Dispose(); publisherStrongReference = null; GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); TestEventPublisher resultPublisher = null; publisherWeakReference.TryGetTarget(out resultPublisher).Is(false); resultPublisher.IsNull(); }
public void FilteredHandlerLifeCycleTest() { var handler1Called = false; var handler2Called = false; var handler3Called = false; var publisher = new TestEventPublisher(); var listener = new PropertyChangedWeakEventListener(publisher); listener.RegisterHandler("Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler1Called = true; }); listener.RegisterHandler("Dummy2", (sender, e) => { e.PropertyName.Is("Dummy2"); handler2Called = true; }); listener.RegisterHandler("Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler3Called = true; }); publisher.RaisePropertyChanged("Dummy1"); publisher.RaisePropertyChanged("Dummy2"); handler1Called.Is(true); handler2Called.Is(true); handler3Called.Is(true); //------------------ handler1Called = false; handler2Called = false; handler3Called = false; listener.Dispose(); publisher.RaisePropertyChanged("Dummy1"); publisher.RaisePropertyChanged("Dummy2"); handler1Called.Is(false); handler2Called.Is(false); handler3Called.Is(false); }
public AccountSelectWindow() { InitializeComponent(); composite = new LivetCompositeDisposable(); ctxlistener = new PropertyChangedWeakEventListener((INotifyPropertyChanged)DataContext); ctxlistener.Add("StartNewAccount", ExpandNewAccount); ctxlistener.Add("FinishNewAccount", CollapseNewAccount); }
public NotificationPage(NotificationViewModel vm) { InitializeComponent(); DataContext = vm; this.vm = vm; composite = new LivetCompositeDisposable(); ctxlistener = new PropertyChangedWeakEventListener((INotifyPropertyChanged)DataContext); }
public MainWindow() { InitializeComponent(); vm = DataContext as MainWindowViewModel; composite = new LivetCompositeDisposable(); ctxlistener = new PropertyChangedWeakEventListener(vm); ctxlistener.Add("AccessTokenRequest", StartAccountSelect); ctxlistener.Add("ReplyStart", ExpandNewTweet); ctxlistener.Add("ToggleNewStatus", ToggleNewTweet); ctxlistener.Add("StatusAction", (s, e) => RequestAction(vm.StatusAction.Type, vm.StatusAction.Information)); ctxlistener.Add("UserTimeline", (s, e) => AddTab("ユーザー定義タブ1", new Frame { NavigationUIVisibility = NavigationUIVisibility.Hidden, Content = new UserCustomizableTimelinePage(vm.UserTimelineViewModel) }, vm.UserTimelineViewModel)); ctxlistener.Add("StatusUpdate", (s, e) => { DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => { if (TabControlMain.SelectedIndex != 0 && setting.MainWindow.NotifyNewStatus) { EmphasisTextBlock(TextBlockTimeline); urs++; TextBlockUnreadStatuses.Text = String.Format(" {0}", urs); } })); }); ctxlistener.Add("EventUpdate", (s, e) => { DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => { if (TabControlMain.SelectedIndex != 1 && setting.MainWindow.NotifyNewNotification) { EmphasisTextBlock(TextBlockNotification); urn++; TextBlockUnreadNotifications.Text = String.Format(" {0}", urn); } })); }); composite.Add(ctxlistener); setting = Kbtter3Extension.LoadJson<Kbtter3Setting>(App.ConfigurationFileName); if (!setting.MainWindow.AllowJokeCommands) ToolBarJokes.Visibility = Visibility.Collapsed; SetShortcuts(); }
public MainWindow() { InitializeComponent(); vm = DataContext as MainWindowViewModel; composite = new LivetCompositeDisposable(); ctxlistener = new PropertyChangedWeakEventListener(vm); ctxlistener.Add("AccessTokenRequest", StartAccountSelect); ctxlistener.Add("ReplyStart", ExpandNewTweet); ctxlistener.Add("ToggleNewStatus", ToggleNewTweet); ctxlistener.Add("StatusAction", (s, e) => RequestAction(vm.StatusAction.Type, vm.StatusAction.Information)); ctxlistener.Add("UserTimeline", (s, e) => AddTab("ユーザー定義タブ1", new Frame { NavigationUIVisibility = NavigationUIVisibility.Hidden, Content = new UserCustomizableTimelinePage(vm.UserTimelineViewModel) }, vm.UserTimelineViewModel)); ctxlistener.Add("StatusUpdate", (s, e) => { DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => { if (TabControlMain.SelectedIndex != 0 && setting.MainWindow.NotifyNewStatus) { EmphasisTextBlock(TextBlockTimeline); urs++; TextBlockUnreadStatuses.Text = String.Format(" {0}", urs); } })); }); ctxlistener.Add("EventUpdate", (s, e) => { DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => { if (TabControlMain.SelectedIndex != 1 && setting.MainWindow.NotifyNewNotification) { EmphasisTextBlock(TextBlockNotification); urn++; TextBlockUnreadNotifications.Text = String.Format(" {0}", urn); } })); }); composite.Add(ctxlistener); setting = Kbtter3Extension.LoadJson <Kbtter3Setting>(App.ConfigurationFileName); if (!setting.MainWindow.AllowJokeCommands) { ToolBarJokes.Visibility = Visibility.Collapsed; } SetShortcuts(); }
public HandlerMemoryLeakTestClass(INotifyPropertyChanged publisher) { Listener = new PropertyChangedWeakEventListener(publisher); // This handler refers "this". PropertyChangedEventHandler handler = (sender, e) => { ToString(); }; Listener.RegisterHandler(handler); Listener.RegisterHandler("Dummy1", handler); }
public StatusPage(StatusViewModel vm) { statvm = vm; DataContext = vm; InitializeComponent(); elm = vm.TextElements; stsn = vm.ScreenName; if (vm.Via == "") StackPanelBlockVia.Visibility = Visibility.Collapsed; SetMainText(); composite = new LivetCompositeDisposable(); ctxlistener = new PropertyChangedWeakEventListener((INotifyPropertyChanged)DataContext); ctxlistener.Add("Delete", DeleteContent); }
public void MultipleHandlerLifeCycleTest() { var handler1Success = false; var handler2Success = false; var publisher = new TestEventPublisher(); var listener = new PropertyChangedWeakEventListener(publisher); //------------------ handler1Success.Is(false); handler2Success.Is(false); publisher.RaisePropertyChanged(string.Empty); handler1Success.Is(false); handler2Success.Is(false); //------------------ listener.RegisterHandler((sender, e) => handler1Success = true); publisher.RaisePropertyChanged(string.Empty); handler1Success.Is(true); handler2Success.Is(false); //------------------ handler1Success = false; handler2Success = false; listener.RegisterHandler((sender, e) => handler2Success = true); publisher.RaisePropertyChanged(string.Empty); handler1Success.Is(true); handler2Success.Is(true); //------------------ handler1Success = false; handler2Success = false; listener.Dispose(); publisher.RaisePropertyChanged(string.Empty); handler1Success.Is(false); handler2Success.Is(false); }
public StatusPage(StatusViewModel vm) { statvm = vm; DataContext = vm; InitializeComponent(); elm = vm.TextElements; stsn = vm.ScreenName; if (vm.Via == "") { StackPanelBlockVia.Visibility = Visibility.Collapsed; } SetMainText(); composite = new LivetCompositeDisposable(); ctxlistener = new PropertyChangedWeakEventListener((INotifyPropertyChanged)DataContext); ctxlistener.Add("Delete", DeleteContent); }
public void MultiThreadHandlerTest() { var publisher = new TestEventPublisher(); var listener = new PropertyChangedWeakEventListener(publisher); var handlerCalledCount = 0; var parentTask = new Task(() => { var tf = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.AttachedToParent); for (int i = 0; i < 50; i++) { tf.StartNew(() => { for (int f = 0; f < 500; f++) { listener.RegisterHandler("Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handlerCalledCount++; }); } }); } }); parentTask.Start(); parentTask.Wait(); handlerCalledCount.Is(0); publisher.RaisePropertyChanged("Dummy1"); handlerCalledCount.Is(25000); handlerCalledCount = 0; listener.Dispose(); publisher.RaisePropertyChanged("Dummy1"); handlerCalledCount.Is(0); }
/// <summary> /// <see cref="ChangeValueWhenModelPropertyChangeAttribute"/> が指定されたプロパティの変更通知を有効化します。 /// </summary> protected void EnableAutoPropertyChangedEvent(INotifyPropertyChanged model) { PropertyChangedWeakEventListener listener = null; foreach (var prop in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { PropertyChangedEventHandler handler = null; foreach (var attr in prop.GetCustomAttributes <ChangeValueWhenModelPropertyChangeAttribute>()) { if (attr.DependentPropertyNames == null) { continue; } foreach (var propName in attr.DependentPropertyNames) { if (listener == null) { listener = new PropertyChangedWeakEventListener(model); } if (handler == null) { handler = CreateHandler(prop.Name); } listener.Add(propName, handler); } } } if (listener != null) { this.CompositeDisposable.Add(listener); } PropertyChangedEventHandler CreateHandler(string propertyName) => (_, __) => this.RaisePropertyChanged(propertyName); }
public void SourceReferenceMemoryLeakTest() { var handler1Called = false; var publisherStrongReference = new TestEventPublisher(); var publisherWeakReference = new WeakReference<TestEventPublisher>(publisherStrongReference); var listener = new PropertyChangedWeakEventListener(publisherStrongReference); listener.RegisterHandler("Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler1Called = true; }); publisherStrongReference.RaisePropertyChanged("Dummy1"); handler1Called.Is(true); listener.Dispose(); publisherStrongReference = null; GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); TestEventPublisher resultPublisher = null; publisherWeakReference.TryGetTarget(out resultPublisher).Is(false); resultPublisher.IsNull(); }
public void AddHandlerKindTest() { var handler1Called = false; var handler2Called = false; var handler3Called = false; var handler4Called = false; var handler5Called = false; var publisher = new TestEventPublisher(); var listener1 = new PropertyChangedWeakEventListener(publisher) { {"Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler1Called = true; }}, {() => publisher.Dummy2, (sender, e) => { e.PropertyName.Is("Dummy2"); handler2Called = true;}, (sender, e) => { e.PropertyName.Is("Dummy2"); handler3Called = true;} }, (sender,e) => handler4Called = true, {"Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler5Called = true; }} }; publisher.RaisePropertyChanged(null); handler1Called.Is(false); handler2Called.Is(false); handler3Called.Is(false); handler4Called.Is(true); handler5Called.Is(false); handler4Called = false; publisher.RaisePropertyChanged("Dummy1"); handler1Called.Is(true); handler2Called.Is(false); handler3Called.Is(false); handler4Called.Is(true); handler5Called.Is(true); handler1Called = false; handler4Called = false; handler5Called = false; publisher.RaisePropertyChanged("Dummy2"); handler1Called.Is(false); handler2Called.Is(true); handler3Called.Is(true); handler4Called.Is(true); handler5Called.Is(false); handler1Called = false; handler2Called = false; handler3Called = false; handler4Called = false; handler5Called = false; listener1.Dispose(); publisher.RaisePropertyChanged("Dummy1"); publisher.RaisePropertyChanged("Dummy2"); handler1Called.Is(false); handler2Called.Is(false); handler3Called.Is(false); handler4Called.Is(false); handler5Called.Is(false); }
public void AddHandlerKindTest() { var handler1Called = false; var handler2Called = false; var handler3Called = false; var handler4Called = false; var handler5Called = false; var publisher = new TestEventPublisher(); var listener1 = new PropertyChangedWeakEventListener(publisher) { { "Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler1Called = true; } }, { () => publisher.Dummy2, (sender, e) => { e.PropertyName.Is("Dummy2"); handler2Called = true; }, (sender, e) => { e.PropertyName.Is("Dummy2"); handler3Called = true; } }, (sender, e) => handler4Called = true, { "Dummy1", (sender, e) => { e.PropertyName.Is("Dummy1"); handler5Called = true; } } }; publisher.RaisePropertyChanged(null); handler1Called.Is(false); handler2Called.Is(false); handler3Called.Is(false); handler4Called.Is(true); handler5Called.Is(false); handler4Called = false; publisher.RaisePropertyChanged("Dummy1"); handler1Called.Is(true); handler2Called.Is(false); handler3Called.Is(false); handler4Called.Is(true); handler5Called.Is(true); handler1Called = false; handler4Called = false; handler5Called = false; publisher.RaisePropertyChanged("Dummy2"); handler1Called.Is(false); handler2Called.Is(true); handler3Called.Is(true); handler4Called.Is(true); handler5Called.Is(false); handler1Called = false; handler2Called = false; handler3Called = false; handler4Called = false; handler5Called = false; listener1.Dispose(); publisher.RaisePropertyChanged("Dummy1"); publisher.RaisePropertyChanged("Dummy2"); handler1Called.Is(false); handler2Called.Is(false); handler3Called.Is(false); handler4Called.Is(false); handler5Called.Is(false); }
/// <summary> /// <see cref="ChangeCanExecuteWhenModelPropertyChangeAttribute"/> および <see cref="ChangeCanExecuteWhenThisPropertyChangeAttribute"/> が指定されたコマンドの <see cref="System.Windows.Input.ICommand.CanExecuteChanged"/> を自動的に発生させるようにします。 /// </summary> protected void EnableAutoCanExecuteChangedEvent(INotifyPropertyChanged model = null) { PropertyChangedEventListener thisListener = null; PropertyChangedWeakEventListener modelListener = null; foreach (var prop in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { PropertyChangedEventHandler handler = null; foreach (var attr in prop.GetCustomAttributes()) { if (attr is ChangeCanExecuteWhenThisPropertyChangeAttribute thisAttr) { if (thisAttr.DependentPropertyNames == null) { continue; } foreach (var propName in thisAttr.DependentPropertyNames) { if (thisListener == null) { thisListener = new PropertyChangedEventListener(this); } if (handler == null) { handler = CreateHandler(prop); } thisListener.Add(propName, handler); } } else if (attr is ChangeCanExecuteWhenModelPropertyChangeAttribute modelAttr) { if (modelAttr.DependentPropertyNames == null) { continue; } if (model == null) { throw new ArgumentNullException(nameof(ChangeCanExecuteWhenModelPropertyChangeAttribute) + " が指定されたプロパティが存在するにもかかわらず " + nameof(model) + " が null です。"); } foreach (var propName in modelAttr.DependentPropertyNames) { if (modelListener == null) { modelListener = new PropertyChangedWeakEventListener(model); } if (handler == null) { handler = CreateHandler(prop); } modelListener.Add(propName, handler); } } } } if (thisListener != null) { this.CompositeDisposable.Add(thisListener); } if (modelListener != null) { this.CompositeDisposable.Add(modelListener); } PropertyChangedEventHandler CreateHandler(PropertyInfo prop) => Expression.Lambda <PropertyChangedEventHandler>( Expression.Call( Expression.Property(Expression.Constant(this), prop), s_viewModelCommandRaiseCanExecuteChangedMethodInfo ), Expression.Parameter(typeof(object)), Expression.Parameter(typeof(PropertyChangedEventArgs)) ).Compile(); }