Browse Source

clean event subscriptions before updating menus.

pull/3762/head
Dan Walmsley 7 years ago
parent
commit
6895ea9dd0
  1. 7
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  2. 11
      src/Avalonia.Native/IAvnAppMenu.cs
  3. 15
      src/Avalonia.Native/IAvnAppMenuItem.cs

7
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@ -16,6 +16,7 @@ namespace Avalonia.Native
private IAvnWindow _nativeWindow; private IAvnWindow _nativeWindow;
private NativeMenu _menu; private NativeMenu _menu;
private IAvnAppMenu _nativeMenu; private IAvnAppMenu _nativeMenu;
private IDisposable _disposable;
public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory) public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory)
{ {
@ -129,7 +130,8 @@ namespace Avalonia.Native
menuItem.Menu = menu; menuItem.Menu = menu;
_nativeMenu.Update(this, _factory, appMenuHolder); _disposable?.Dispose();
_disposable = _nativeMenu.Update(this, _factory, appMenuHolder);
_factory.SetAppMenu(_nativeMenu); _factory.SetAppMenu(_nativeMenu);
} }
@ -146,7 +148,8 @@ namespace Avalonia.Native
} }
} }
_nativeMenu.Update(this, _factory, menu); _disposable?.Dispose();
_disposable = _nativeMenu.Update(this, _factory, menu);
avnWindow.SetMainMenu(_nativeMenu); avnWindow.SetMainMenu(_nativeMenu);
} }

11
src/Avalonia.Native/IAvnAppMenu.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Reactive.Disposables;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform.Interop; using Avalonia.Platform.Interop;
@ -42,8 +43,10 @@ namespace Avalonia.Native.Interop
return nativeItem; return nativeItem;
} }
internal void Update(AvaloniaNativeMenuExporter exporter, IAvaloniaNativeFactory factory, NativeMenu menu, string title = "") internal IDisposable Update(AvaloniaNativeMenuExporter exporter, IAvaloniaNativeFactory factory, NativeMenu menu, string title = "")
{ {
var disposables = new CompositeDisposable();
if (_menu == null) if (_menu == null)
{ {
_menu = menu; _menu = menu;
@ -57,6 +60,8 @@ namespace Avalonia.Native.Interop
((INotifyCollectionChanged)_menu.Items).CollectionChanged += IAvnAppMenu_CollectionChanged; ((INotifyCollectionChanged)_menu.Items).CollectionChanged += IAvnAppMenu_CollectionChanged;
disposables.Add(Disposable.Create(() => ((INotifyCollectionChanged)_menu.Items).CollectionChanged -= IAvnAppMenu_CollectionChanged));
if (!string.IsNullOrWhiteSpace(title)) if (!string.IsNullOrWhiteSpace(title))
{ {
using (var buffer = new Utf8Buffer(title)) using (var buffer = new Utf8Buffer(title))
@ -88,7 +93,7 @@ namespace Avalonia.Native.Interop
if (menu.Items[i] is NativeMenuItem nmi) if (menu.Items[i] is NativeMenuItem nmi)
{ {
nativeItem.Update(exporter, factory, nmi); disposables.Add(nativeItem.Update(exporter, factory, nmi));
} }
InsertAt(i, nativeItem); InsertAt(i, nativeItem);
@ -98,6 +103,8 @@ namespace Avalonia.Native.Interop
{ {
Remove(_menuItems[i]); Remove(_menuItems[i]);
} }
return disposables;
} }
private void IAvnAppMenu_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) private void IAvnAppMenu_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)

15
src/Avalonia.Native/IAvnAppMenuItem.cs

@ -1,4 +1,6 @@
using Avalonia.Controls; using System;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Platform.Interop; using Avalonia.Platform.Interop;
namespace Avalonia.Native.Interop namespace Avalonia.Native.Interop
@ -10,14 +12,18 @@ namespace Avalonia.Native.Interop
public NativeMenuItemBase Managed { get; set; } public NativeMenuItemBase Managed { get; set; }
internal void Update(AvaloniaNativeMenuExporter exporter, IAvaloniaNativeFactory factory, NativeMenuItem item) internal IDisposable Update(AvaloniaNativeMenuExporter exporter, IAvaloniaNativeFactory factory, NativeMenuItem item)
{ {
var disposables = new CompositeDisposable();
_exporter = exporter; _exporter = exporter;
Managed = item; Managed = item;
Managed.PropertyChanged += Item_PropertyChanged; Managed.PropertyChanged += Item_PropertyChanged;
disposables.Add(Disposable.Create(() => Managed.PropertyChanged -= Item_PropertyChanged));
if(!string.IsNullOrWhiteSpace(item.Header)) if(!string.IsNullOrWhiteSpace(item.Header))
{ {
using (var buffer = new Utf8Buffer(item.Header)) using (var buffer = new Utf8Buffer(item.Header))
@ -52,7 +58,8 @@ namespace Avalonia.Native.Interop
} }
SetSubMenu(_subMenu); SetSubMenu(_subMenu);
_subMenu.Update(exporter, factory, item.Menu, item.Header);
disposables.Add(_subMenu.Update(exporter, factory, item.Menu, item.Header));
} }
if (item.Menu == null && _subMenu != null) if (item.Menu == null && _subMenu != null)
@ -61,6 +68,8 @@ namespace Avalonia.Native.Interop
// needs implementing on native side also. // needs implementing on native side also.
} }
return disposables;
} }
private void Item_PropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) private void Item_PropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e)

Loading…
Cancel
Save