Refactor SwitchKnob bindings

This commit is contained in:
qinware
2025-09-05 16:06:46 +08:00
parent a36cf48c2a
commit 77258c6ca9
9 changed files with 103 additions and 132 deletions
@@ -1,9 +1,7 @@
using System.Reactive.Disposables;
using AtomUI.Animations;
using AtomUI.Controls.Themes;
using AtomUI.Controls.Utils;
using AtomUI.IconPkg;
using AtomUI.Theme;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using Avalonia;
@@ -13,14 +11,13 @@ using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.Media;
namespace AtomUI.Controls;
using AvaloniaRadioButton = Avalonia.Controls.RadioButton;
internal class PaletteColorItem : AvaloniaRadioButton, IResourceBindingManager
internal class PaletteColorItem : AvaloniaRadioButton
{
#region 公共属性定义
@@ -61,8 +58,8 @@ internal class PaletteColorItem : AvaloniaRadioButton, IResourceBindingManager
}
#endregion
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
private Icon? _checkedMark;
private IDisposable? _borderThicknessDisposable;
static PaletteColorItem()
{
@@ -92,19 +89,19 @@ internal class PaletteColorItem : AvaloniaRadioButton, IResourceBindingManager
}
}
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
base.OnAttachedToVisualTree(e);
_borderThicknessDisposable = TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
SharedTokenKey.BorderThickness,
BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this)));
new RenderScaleAwareThicknessConfigure(this));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
this.DisposeTokenBindings();
base.OnDetachedFromVisualTree(e);
_borderThicknessDisposable?.Dispose();
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+24 -27
View File
@@ -31,8 +31,7 @@ public class SplitButton : ContentControl,
ICommandSource,
ISizeTypeAware,
IControlSharedTokenResourcesHost,
IWaveSpiritAwareControl,
IResourceBindingManager
IWaveSpiritAwareControl
{
#region 公共属性定义
@@ -274,7 +273,6 @@ public class SplitButton : ContentControl,
Control IMotionAwareControl.PropertyBindTarget => this;
Control IControlSharedTokenResourcesHost.HostControl => this;
string IControlSharedTokenResourcesHost.TokenId => ButtonToken.ID;
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
#endregion
@@ -289,6 +287,7 @@ public class SplitButton : ContentControl,
private CompositeDisposable? _flyoutBindingDisposables;
private CompositeDisposable? _flyoutHelperBindingDisposables;
private IDisposable? _borderThicknessDisposable;
static SplitButton()
{
@@ -312,8 +311,7 @@ public class SplitButton : ContentControl,
{
CanExecuteChanged(sender, e);
}
/// <inheritdoc cref="ICommandSource.CanExecuteChanged" />
private void CanExecuteChanged(object? sender, EventArgs e)
{
var (command, parameter) = (Command, CommandParameter);
@@ -424,22 +422,6 @@ public class SplitButton : ContentControl,
_primaryButton.Click -= HandlePrimaryButtonClick;
}
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_flyoutStateHelper.NotifyAttachedToVisualTree();
UpdatePseudoClasses();
RegisterFlyoutEvents(Flyout);
SetupDefaultFlyoutButtonIcon();
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
UnregisterFlyoutEvents(Flyout);
_flyoutStateHelper.NotifyDetachedFromVisualTree();
}
private void SetupDefaultFlyoutButtonIcon()
{
@@ -465,6 +447,27 @@ public class SplitButton : ContentControl,
_primaryButton.Click += HandlePrimaryButtonClick;
}
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_borderThicknessDisposable = TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
SharedTokenKey.BorderThickness,
BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this));
_flyoutStateHelper.NotifyAttachedToVisualTree();
UpdatePseudoClasses();
RegisterFlyoutEvents(Flyout);
SetupDefaultFlyoutButtonIcon();
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
UnregisterFlyoutEvents(Flyout);
_flyoutStateHelper.NotifyDetachedFromVisualTree();
_borderThicknessDisposable?.Dispose();
}
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
@@ -487,11 +490,6 @@ public class SplitButton : ContentControl,
_flyoutHelperBindingDisposables.Add(BindUtils.RelayBind(this, MouseLeaveDelayProperty, _flyoutStateHelper,
FlyoutStateHelper.MouseLeaveDelayProperty));
_flyoutHelperBindingDisposables.Add(BindUtils.RelayBind(this, TriggerTypeProperty, _flyoutStateHelper, FlyoutStateHelper.TriggerTypeProperty));
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, Border.BorderThicknessProperty,
SharedTokenKey.BorderThickness,
BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this)));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
@@ -507,7 +505,6 @@ public class SplitButton : ContentControl,
Command.CanExecuteChanged -= CanExecuteChanged;
}
_flyoutHelperBindingDisposables?.Dispose();
this.DisposeTokenBindings();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e)
+11 -19
View File
@@ -1,6 +1,4 @@
using System.Reactive.Disposables;
using AtomUI.Controls.Themes;
using AtomUI.Theme;
using AtomUI.Controls.Themes;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using Avalonia;
@@ -8,7 +6,6 @@ using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
namespace AtomUI.Controls;
@@ -18,7 +15,7 @@ public enum SearchEditButtonStyle
Primary
}
public class SearchEdit : LineEdit, IResourceBindingManager
public class SearchEdit : LineEdit
{
#region 公共属性定义
@@ -41,13 +38,6 @@ public class SearchEdit : LineEdit, IResourceBindingManager
}
#endregion
#region 内部属性定义
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
#endregion
#region 公共事件定义
@@ -61,20 +51,22 @@ public class SearchEdit : LineEdit, IResourceBindingManager
}
#endregion
private IDisposable? _borderThicknessDisposable;
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
base.OnAttachedToVisualTree(e);
_borderThicknessDisposable = TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
SharedTokenKey.BorderThickness,
BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this)));
new RenderScaleAwareThicknessConfigure(this));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
this.DisposeTokenBindings();
base.OnDetachedFromVisualTree(e);
_borderThicknessDisposable?.Dispose();
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+9 -16
View File
@@ -2,7 +2,6 @@
using System.Reactive.Disposables;
using AtomUI.Controls.Themes;
using AtomUI.Data;
using AtomUI.Theme;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using Avalonia;
@@ -40,7 +39,7 @@ public class NavMenuItemClickEventArgs : RoutedEventArgs
NavMenuPseudoClass.VerticalMode,
NavMenuPseudoClass.DarkStyle,
NavMenuPseudoClass.LightStyle)]
public class NavMenu : NavMenuBase, IResourceBindingManager
public class NavMenu : NavMenuBase
{
#region 公共属性定义
@@ -108,15 +107,14 @@ public class NavMenu : NavMenuBase, IResourceBindingManager
get => GetValue(HorizontalBorderThicknessProperty);
set => SetValue(HorizontalBorderThicknessProperty, value);
}
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
#endregion
private static readonly FuncTemplate<Panel?> DefaultPanel =
new(() => new StackPanel { Orientation = Orientation.Vertical });
private ItemsPresenter? _menuItemsPresenter;
private readonly Dictionary<NavMenuItem, CompositeDisposable> _itemsBindingDisposables = new();
private IDisposable? _borderThicknessDisposable;
static NavMenu()
{
@@ -296,28 +294,23 @@ public class NavMenu : NavMenuBase, IResourceBindingManager
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, HorizontalBorderThicknessProperty,
SharedTokenKey.LineWidth,
BindingPriority.Template,
new RenderScaleAwareDoubleConfigure(this)));
SetupInteractionHandler();
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
this.DisposeTokenBindings();
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_borderThicknessDisposable = TokenResourceBinder.CreateTokenBinding(this, HorizontalBorderThicknessProperty,
SharedTokenKey.LineWidth,
BindingPriority.Template,
new RenderScaleAwareDoubleConfigure(this));
InteractionHandler?.Attach(this);
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
_borderThicknessDisposable?.Dispose();
InteractionHandler?.Detach(this);
}
@@ -1,8 +1,6 @@
using System.Reactive.Disposables;
using AtomUI.Animations;
using AtomUI.Controls.Utils;
using AtomUI.IconPkg;
using AtomUI.Theme;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using Avalonia;
@@ -12,7 +10,6 @@ using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
namespace AtomUI.Controls;
@@ -25,9 +22,7 @@ internal enum PaginationItemType
Ellipses
}
internal class PaginationNavItem : ContentControl,
ISelectable,
IResourceBindingManager
internal class PaginationNavItem : ContentControl, ISelectable
{
public static readonly StyledProperty<bool> IsSelectedProperty =
SelectingItemsControl.IsSelectedProperty.AddOwner<PaginationNavItem>();
@@ -93,9 +88,8 @@ internal class PaginationNavItem : ContentControl,
private set => SetAndRaise(IsPressedProperty, ref _isPressed, value);
}
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
internal int PageNumber { get; set; } = -1;
private IDisposable? _borderThicknessDisposable;
static PaginationNavItem()
{
@@ -106,19 +100,19 @@ internal class PaginationNavItem : ContentControl,
AffectsRender<PaginationNavItem>(BackgroundProperty, BorderBrushProperty);
}
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
base.OnAttachedToVisualTree(e);
_borderThicknessDisposable = TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
SharedTokenKey.BorderThickness,
BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this)));
new RenderScaleAwareThicknessConfigure(this));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
this.DisposeTokenBindings();
base.OnDetachedFromVisualTree(e);
_borderThicknessDisposable?.Dispose();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+6 -9
View File
@@ -24,9 +24,7 @@ namespace AtomUI.Controls;
using AvaloniaPopup = Avalonia.Controls.Primitives.Popup;
public class Popup : AvaloniaPopup,
IWaveSpiritAwareControl,
IResourceBindingManager
public class Popup : AvaloniaPopup, IWaveSpiritAwareControl
{
#region 公共属性定义
@@ -147,8 +145,6 @@ public class Popup : AvaloniaPopup,
Control IMotionAwareControl.PropertyBindTarget => this;
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
#endregion
internal BaseMotionActor? MotionActor;
@@ -157,6 +153,7 @@ public class Popup : AvaloniaPopup,
private IManagedPopupPositionerPopup? _managedPopupPositioner;
private bool _isNeedDetectFlip = true;
private bool _ignoreIsOpenChanged;
private CompositeDisposable? _tokenBindingDisposables;
// 在翻转之后或者恢复正常,会有属性的变动,在变动之后捕捉动画需要等一个事件循环,保证布局已经生效
private bool _isNeedWaitFlipSync;
@@ -204,16 +201,16 @@ public class Popup : AvaloniaPopup,
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
this.AddResourceBindingDisposable(
TokenResourceBinder.CreateTokenBinding(this, MaskShadowsProperty, SharedTokenKey.BoxShadowsSecondary));
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, MotionDurationProperty,
_tokenBindingDisposables = new CompositeDisposable(2);
_tokenBindingDisposables.Add(TokenResourceBinder.CreateTokenBinding(this, MaskShadowsProperty, SharedTokenKey.BoxShadowsSecondary));
_tokenBindingDisposables.Add(TokenResourceBinder.CreateTokenBinding(this, MotionDurationProperty,
SharedTokenKey.MotionDurationMid));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
this.DisposeTokenBindings();
_tokenBindingDisposables?.Dispose();
}
protected Control? GetEffectivePlacementTarget()
@@ -11,15 +11,12 @@ using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.VisualTree;
namespace AtomUI.Controls;
internal class RadioIndicator : Control,
IWaveAdornerInfoProvider,
IResourceBindingManager
internal class RadioIndicator : Control, IWaveAdornerInfoProvider
{
#region 公共属性定义
@@ -136,11 +133,11 @@ internal class RadioIndicator : Control,
get => GetValue(IsWaveAnimationEnabledProperty);
set => SetValue(IsWaveAnimationEnabledProperty, value);
}
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
#endregion
private IPen? _cachedPen;
private IDisposable? _borderThicknessDisposable;
static RadioIndicator()
{
@@ -164,28 +161,24 @@ internal class RadioIndicator : Control,
base.OnUnloaded(e);
Transitions = null;
}
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, RadioBorderThicknessProperty,
SharedTokenKey.BorderThickness, BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this)));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
this.DisposeTokenBindings();
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_borderThicknessDisposable = TokenResourceBinder.CreateTokenBinding(this, RadioBorderThicknessProperty,
SharedTokenKey.BorderThickness,
BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this));
RadioDotEffectSize = CalculateDotSize(IsEnabled, IsChecked.HasValue && IsChecked.Value);
UpdatePseudoClasses();
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
_borderThicknessDisposable?.Dispose();
}
private void ConfigureTransitions(bool force)
{
if (IsMotionEnabled)
+6 -7
View File
@@ -2,7 +2,6 @@ using System.Reactive.Disposables;
using AtomUI.Controls.Utils;
using AtomUI.Data;
using AtomUI.Media;
using AtomUI.Theme;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
@@ -18,7 +17,7 @@ using Avalonia.VisualTree;
namespace AtomUI.Controls;
internal class SwitchKnob : Control, IResourceBindingManager
internal class SwitchKnob : Control
{
#region 公共属性定义
@@ -119,13 +118,12 @@ internal class SwitchKnob : Control, IResourceBindingManager
set => SetAndRaise(LoadingBgOpacityProperty, ref _loadingBgOpacity, value);
}
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable { get; set; }
#endregion
private bool _isLoading;
private CancellationTokenSource? _cancellationTokenSource;
private IDisposable? _bindingDisposable;
private CompositeDisposable? _tokenBindingDisposables;
static SwitchKnob()
{
@@ -254,16 +252,17 @@ internal class SwitchKnob : Control, IResourceBindingManager
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, LoadingBgOpacityProperty,
_tokenBindingDisposables = new CompositeDisposable(2);
_tokenBindingDisposables.Add(TokenResourceBinder.CreateTokenBinding(this, LoadingBgOpacityProperty,
ToggleSwitchTokenKey.SwitchDisabledOpacity));
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, LoadingAnimationDurationProperty,
_tokenBindingDisposables.Add(TokenResourceBinder.CreateTokenBinding(this, LoadingAnimationDurationProperty,
ToggleSwitchTokenKey.LoadingAnimationDuration));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
this.DisposeTokenBindings();
_tokenBindingDisposables?.Dispose();
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
@@ -1,12 +1,13 @@
using System.Reactive.Disposables;
using AtomUI.Controls.Utils;
using AtomUI.Media.TextFormatting;
using AtomUI.Theme;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.Media.TextFormatting;
using Avalonia.Utilities;
@@ -43,6 +44,7 @@ public class SelectableTextBlock : TextBlock
private bool _canCopy;
private int _wordSelectionStart = -1;
private CompositeDisposable? _tokenBindingDisposables;
static SelectableTextBlock()
{
@@ -496,12 +498,19 @@ public class SelectableTextBlock : TextBlock
return selectedText;
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, SelectionBrushProperty,
base.OnAttachedToLogicalTree(e);
_tokenBindingDisposables = new CompositeDisposable(2);
_tokenBindingDisposables.Add(TokenResourceBinder.CreateTokenBinding(this, SelectionBrushProperty,
SharedTokenKey.SelectionBackground));
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, SelectionForegroundBrushProperty,
_tokenBindingDisposables.Add(TokenResourceBinder.CreateTokenBinding(this, SelectionForegroundBrushProperty,
SharedTokenKey.SelectionForeground));
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
_tokenBindingDisposables?.Dispose();
}
}