mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-22 17:35:30 +08:00
Refactor Flyout Bindings
This commit is contained in:
@@ -104,7 +104,9 @@ public class Flyout : PopupFlyoutBase
|
||||
#endregion
|
||||
|
||||
private Classes? _classes;
|
||||
|
||||
private CompositeDisposable? _presenterBindingDisposables;
|
||||
private CompositeDisposable? _popupBindingDisposables;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Classes collection to apply to the FlyoutPresenter this Flyout is hosting
|
||||
/// </summary>
|
||||
@@ -150,12 +152,12 @@ public class Flyout : PopupFlyoutBase
|
||||
|
||||
protected override Control CreatePresenter()
|
||||
{
|
||||
var presenter = new FlyoutPresenter
|
||||
{
|
||||
[!FlyoutPresenter.ContentProperty] = this[!ContentProperty],
|
||||
[!FlyoutPresenter.IsMotionEnabledProperty] = this[!IsMotionEnabledProperty],
|
||||
[!FlyoutPresenter.IsShowArrowProperty] = this[!IsShowArrowEffectiveProperty],
|
||||
};
|
||||
_presenterBindingDisposables?.Dispose();
|
||||
_presenterBindingDisposables = new CompositeDisposable(3);
|
||||
var presenter = new FlyoutPresenter();
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, ContentProperty, presenter, FlyoutPresenter.ContentProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, presenter, FlyoutPresenter.IsMotionEnabledProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, presenter, FlyoutPresenter.IsShowArrowProperty));
|
||||
CalculateShowArrowEffective();
|
||||
SetupArrowPosition(Popup, presenter);
|
||||
return presenter;
|
||||
@@ -164,11 +166,13 @@ public class Flyout : PopupFlyoutBase
|
||||
protected internal override void NotifyPopupCreated(Popup popup)
|
||||
{
|
||||
base.NotifyPopupCreated(popup);
|
||||
BindUtils.RelayBind(this, PlacementProperty, popup, Popup.PlacementProperty);
|
||||
BindUtils.RelayBind(this, PlacementAnchorProperty, popup, Popup.PlacementAnchorProperty);
|
||||
BindUtils.RelayBind(this, PlacementGravityProperty, popup, Popup.PlacementGravityProperty);
|
||||
BindUtils.RelayBind(this, MaskShadowsProperty, popup, Popup.MaskShadowsProperty);
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, popup, Popup.IsMotionEnabledProperty);
|
||||
_popupBindingDisposables?.Dispose();
|
||||
_popupBindingDisposables = new CompositeDisposable(5);
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, PlacementProperty, popup, Popup.PlacementProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, PlacementAnchorProperty, popup, Popup.PlacementAnchorProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, PlacementGravityProperty, popup, Popup.PlacementGravityProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, MaskShadowsProperty, popup, Popup.MaskShadowsProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, popup, Popup.IsMotionEnabledProperty));
|
||||
SetupArrowPosition(popup);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Data;
|
||||
using Avalonia;
|
||||
@@ -44,17 +45,17 @@ public class MenuFlyout : Flyout
|
||||
get => GetValue(ItemTemplateProperty);
|
||||
set => SetValue(ItemTemplateProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Func<IPopupHostProvider, RawPointerEventArgs, bool>? ClickHideFlyoutPredicate;
|
||||
|
||||
private IDisposable? _detectMouseClickDisposable;
|
||||
private MenuFlyoutPresenter? _presenter;
|
||||
|
||||
[Content]
|
||||
public ItemCollection Items { get; }
|
||||
|
||||
public Func<IPopupHostProvider, RawPointerEventArgs, bool>? ClickHideFlyoutPredicate;
|
||||
#endregion
|
||||
|
||||
private IDisposable? _detectMouseClickDisposable;
|
||||
private MenuFlyoutPresenter? _presenter;
|
||||
private CompositeDisposable? _presenterBindingDisposables;
|
||||
|
||||
public MenuFlyout()
|
||||
{
|
||||
var itemCollectionType = typeof(ItemCollection);
|
||||
@@ -63,16 +64,16 @@ public class MenuFlyout : Flyout
|
||||
|
||||
protected override Control CreatePresenter()
|
||||
{
|
||||
_presenterBindingDisposables?.Dispose();
|
||||
_presenterBindingDisposables = new CompositeDisposable(4);
|
||||
_presenter = new MenuFlyoutPresenter
|
||||
{
|
||||
ItemsSource = Items,
|
||||
[!ItemsControl.ItemTemplateProperty] = this[!ItemTemplateProperty],
|
||||
[!ItemsControl.ItemContainerThemeProperty] = this[!ItemContainerThemeProperty],
|
||||
[!MenuFlyoutPresenter.IsMotionEnabledProperty] = this[!IsMotionEnabledProperty],
|
||||
MenuFlyout = this
|
||||
MenuFlyout = this
|
||||
};
|
||||
BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, _presenter, MenuFlyoutPresenter.IsShowArrowProperty);
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, _presenter, MenuFlyoutPresenter.IsMotionEnabledProperty);
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, ItemTemplateProperty, _presenter, MenuFlyoutPresenter.ItemTemplateProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, ItemContainerThemeProperty, _presenter, MenuFlyoutPresenter.ItemContainerThemeProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, _presenter, MenuFlyoutPresenter.IsShowArrowProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, _presenter, MenuFlyoutPresenter.IsMotionEnabledProperty));
|
||||
SetupArrowPosition(Popup, _presenter);
|
||||
CalculateShowArrowEffective();
|
||||
|
||||
@@ -173,6 +174,7 @@ public class MenuFlyout : Flyout
|
||||
{
|
||||
if (_detectMouseClickDisposable is not null)
|
||||
{
|
||||
_detectMouseClickDisposable.Dispose();
|
||||
CompositeDisposable?.Remove(_detectMouseClickDisposable);
|
||||
}
|
||||
|
||||
@@ -184,6 +186,7 @@ public class MenuFlyout : Flyout
|
||||
{
|
||||
if (_detectMouseClickDisposable is not null)
|
||||
{
|
||||
_detectMouseClickDisposable.Dispose();
|
||||
CompositeDisposable?.Remove(_detectMouseClickDisposable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Themes;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Theme;
|
||||
@@ -76,17 +78,41 @@ public class MenuFlyoutPresenter : MenuBase,
|
||||
#endregion
|
||||
|
||||
private ArrowDecoratedBox? _arrowDecoratedBox;
|
||||
private Dictionary<MenuItem, CompositeDisposable> _itemsBindingDisposables = new();
|
||||
|
||||
public MenuFlyoutPresenter()
|
||||
: base(new DefaultMenuInteractionHandler(true))
|
||||
{
|
||||
this.RegisterResources();
|
||||
Items.CollectionChanged += HandleCollectionChanged;
|
||||
}
|
||||
|
||||
public MenuFlyoutPresenter(IMenuInteractionHandler menuInteractionHandler)
|
||||
: base(menuInteractionHandler)
|
||||
{
|
||||
this.RegisterResources();
|
||||
Items.CollectionChanged += HandleCollectionChanged;
|
||||
}
|
||||
|
||||
private void HandleCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
if (e.Action == NotifyCollectionChangedAction.Remove && e.OldItems.Count > 0)
|
||||
{
|
||||
foreach (var item in e.OldItems)
|
||||
{
|
||||
if (item is MenuItem menuItem)
|
||||
{
|
||||
if (_itemsBindingDisposables.TryGetValue(menuItem, out var disposable))
|
||||
{
|
||||
disposable.Dispose();
|
||||
_itemsBindingDisposables.Remove(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
@@ -244,7 +270,14 @@ public class MenuFlyoutPresenter : MenuBase,
|
||||
{
|
||||
if (container is MenuItem menuItem)
|
||||
{
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, menuItem, MenuItem.IsMotionEnabledProperty);
|
||||
var disposables = new CompositeDisposable(1);
|
||||
disposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, menuItem, MenuItem.IsMotionEnabledProperty));
|
||||
if (_itemsBindingDisposables.TryGetValue(menuItem, out var oldDisposables))
|
||||
{
|
||||
oldDisposables.Dispose();
|
||||
_itemsBindingDisposables.Remove(menuItem);
|
||||
}
|
||||
_itemsBindingDisposables.Add(menuItem, disposables);
|
||||
}
|
||||
|
||||
base.PrepareContainerForItemOverride(container, item, index);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.MotionScene;
|
||||
@@ -226,6 +227,7 @@ public abstract class PopupFlyoutBase : FlyoutBase, IPopupHostProvider
|
||||
private PixelRect? _enlargePopupRectScreenPixelRect;
|
||||
private IDisposable? _transientDisposable;
|
||||
private Action<IPopupHost?>? _popupHostChangedHandler;
|
||||
private CompositeDisposable? _popupBindingDisposables;
|
||||
|
||||
static PopupFlyoutBase()
|
||||
{
|
||||
@@ -239,12 +241,14 @@ public abstract class PopupFlyoutBase : FlyoutBase, IPopupHostProvider
|
||||
|
||||
protected internal virtual void NotifyPopupCreated(Popup popup)
|
||||
{
|
||||
BindUtils.RelayBind(this, MarginToAnchorProperty, popup);
|
||||
BindUtils.RelayBind(this, IsDetectMouseClickEnabledProperty, popup, Popup.IsDetectMouseClickEnabledProperty);
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, popup, Popup.IsMotionEnabledProperty);
|
||||
BindUtils.RelayBind(this, MotionDurationProperty, popup, Popup.MotionDurationProperty);
|
||||
BindUtils.RelayBind(this, OpenMotionProperty, popup, Popup.OpenMotionProperty);
|
||||
BindUtils.RelayBind(this, CloseMotionProperty, popup, Popup.CloseMotionProperty);
|
||||
_popupBindingDisposables?.Dispose();
|
||||
_popupBindingDisposables = new CompositeDisposable(6);
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, MarginToAnchorProperty, popup));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, IsDetectMouseClickEnabledProperty, popup, Popup.IsDetectMouseClickEnabledProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, popup, Popup.IsMotionEnabledProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, MotionDurationProperty, popup, Popup.MotionDurationProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, OpenMotionProperty, popup, Popup.OpenMotionProperty));
|
||||
_popupBindingDisposables.Add(BindUtils.RelayBind(this, CloseMotionProperty, popup, Popup.CloseMotionProperty));
|
||||
PopupCreated?.Invoke(this, new FlyoutPopupCreatedEventArgs(popup));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Data;
|
||||
using Avalonia;
|
||||
@@ -44,15 +45,15 @@ public class TreeViewFlyout : Flyout
|
||||
get => GetValue(ItemTemplateProperty);
|
||||
set => SetValue(ItemTemplateProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
[Content] public ItemCollection Items { get; }
|
||||
public Func<IPopupHostProvider, RawPointerEventArgs, bool>? ClickHideFlyoutPredicate;
|
||||
|
||||
#endregion
|
||||
|
||||
private IDisposable? _detectMouseClickDisposable;
|
||||
|
||||
[Content] public ItemCollection Items { get; }
|
||||
|
||||
private CompositeDisposable? _presenterBindingDisposables;
|
||||
|
||||
public TreeViewFlyout()
|
||||
{
|
||||
var itemCollectionType = typeof(ItemCollection);
|
||||
@@ -61,16 +62,17 @@ public class TreeViewFlyout : Flyout
|
||||
|
||||
protected override Control CreatePresenter()
|
||||
{
|
||||
_presenterBindingDisposables?.Dispose();
|
||||
_presenterBindingDisposables = new CompositeDisposable(4);
|
||||
var presenter = new TreeViewFlyoutPresenter
|
||||
{
|
||||
ItemsSource = Items,
|
||||
[!ItemsControl.ItemTemplateProperty] = this[!ItemTemplateProperty],
|
||||
[!ItemsControl.ItemContainerThemeProperty] = this[!ItemContainerThemeProperty],
|
||||
|
||||
ItemsSource = Items
|
||||
};
|
||||
presenter.TreeViewFlyout = this;
|
||||
BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, presenter, TreeViewFlyoutPresenter.IsShowArrowProperty);
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, presenter, TreeViewFlyoutPresenter.IsMotionEnabledProperty);
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, ItemTemplateProperty, presenter, TreeViewFlyoutPresenter.ItemTemplateProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, ItemContainerThemeProperty, presenter, TreeViewFlyoutPresenter.ItemContainerThemeProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, presenter, TreeViewFlyoutPresenter.IsShowArrowProperty));
|
||||
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, presenter, TreeViewFlyoutPresenter.IsMotionEnabledProperty));
|
||||
SetupArrowPosition(Popup, presenter);
|
||||
CalculateShowArrowEffective();
|
||||
|
||||
@@ -172,6 +174,7 @@ public class TreeViewFlyout : Flyout
|
||||
{
|
||||
if (_detectMouseClickDisposable is not null)
|
||||
{
|
||||
_detectMouseClickDisposable.Dispose();
|
||||
CompositeDisposable?.Remove(_detectMouseClickDisposable);
|
||||
}
|
||||
|
||||
@@ -183,6 +186,7 @@ public class TreeViewFlyout : Flyout
|
||||
{
|
||||
if (_detectMouseClickDisposable is not null)
|
||||
{
|
||||
_detectMouseClickDisposable.Dispose();
|
||||
CompositeDisposable?.Remove(_detectMouseClickDisposable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Themes;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Theme;
|
||||
@@ -68,16 +70,41 @@ public class TreeViewFlyoutPresenter : FloatableTreeView,
|
||||
|
||||
#endregion
|
||||
|
||||
private Dictionary<MenuItem, CompositeDisposable> _itemsBindingDisposables = new();
|
||||
|
||||
public TreeViewFlyoutPresenter()
|
||||
: base(new DefaultTreeViewInteractionHandler(true))
|
||||
{
|
||||
this.RegisterResources();
|
||||
Items.CollectionChanged += HandleCollectionChanged;
|
||||
}
|
||||
|
||||
public TreeViewFlyoutPresenter(ITreeViewInteractionHandler menuInteractionHandler)
|
||||
: base(menuInteractionHandler)
|
||||
{
|
||||
this.RegisterResources();
|
||||
Items.CollectionChanged += HandleCollectionChanged;
|
||||
}
|
||||
|
||||
private void HandleCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
if (e.Action == NotifyCollectionChangedAction.Remove && e.OldItems.Count > 0)
|
||||
{
|
||||
foreach (var item in e.OldItems)
|
||||
{
|
||||
if (item is MenuItem menuItem)
|
||||
{
|
||||
if (_itemsBindingDisposables.TryGetValue(menuItem, out var disposable))
|
||||
{
|
||||
disposable.Dispose();
|
||||
_itemsBindingDisposables.Remove(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ContainerForItemPreparedOverride(Control container, object? item, int index)
|
||||
@@ -172,7 +199,14 @@ public class TreeViewFlyoutPresenter : FloatableTreeView,
|
||||
{
|
||||
if (container is MenuItem menuItem)
|
||||
{
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, menuItem, MenuItem.IsMotionEnabledProperty);
|
||||
var disposables = new CompositeDisposable(1);
|
||||
disposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, menuItem, MenuItem.IsMotionEnabledProperty));
|
||||
if (_itemsBindingDisposables.TryGetValue(menuItem, out var oldDisposables))
|
||||
{
|
||||
oldDisposables.Dispose();
|
||||
_itemsBindingDisposables.Remove(menuItem);
|
||||
}
|
||||
_itemsBindingDisposables.Add(menuItem, disposables);
|
||||
}
|
||||
|
||||
base.PrepareContainerForItemOverride(container, item, index);
|
||||
|
||||
Reference in New Issue
Block a user