diff --git a/src/AtomUI.Controls/Expander/Expander.cs b/src/AtomUI.Controls/Expander/Expander.cs index 278a3439d..005b28da8 100644 --- a/src/AtomUI.Controls/Expander/Expander.cs +++ b/src/AtomUI.Controls/Expander/Expander.cs @@ -228,18 +228,19 @@ public class Expander : AvaloniaExpander, this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty, SharedTokenKey.BorderThickness, BindingPriority.Template, new RenderScaleAwareThicknessConfigure(this))); + SetupEffectiveBorderThickness(); + SetupExpanderBorderThickness(); + SetupDefaultIcon(); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - SetupDefaultIcon(); base.OnApplyTemplate(e); this.RunThemeTokenBindingActions(); _motionActor = e.NameScope.Find(ExpanderTheme.ContentMotionActorPart); _headerDecorator = e.NameScope.Find(ExpanderTheme.HeaderDecoratorPart); _expandButton = e.NameScope.Find(ExpanderTheme.ExpandButtonPart); - SetupEffectiveBorderThickness(); - SetupExpanderBorderThickness(); + _tempAnimationDisabled = true; HandleExpandedChanged(); _tempAnimationDisabled = false; @@ -276,16 +277,12 @@ public class Expander : AvaloniaExpander, SetupDefaultIcon(); } - } - - if (this.IsAttachedToVisualTree()) - { - if (change.Property == IsBorderlessProperty) + else if (change.Property == IsBorderlessProperty) { SetupEffectiveBorderThickness(); } } - + if (change.Property == ExpandIconProperty) { if (change.OldValue is Icon oldIcon) diff --git a/src/AtomUI.Controls/Flyouts/FlyoutHost.cs b/src/AtomUI.Controls/Flyouts/FlyoutHost.cs index 0f12e72a0..2a20b504f 100644 --- a/src/AtomUI.Controls/Flyouts/FlyoutHost.cs +++ b/src/AtomUI.Controls/Flyouts/FlyoutHost.cs @@ -192,17 +192,6 @@ public class FlyoutHost : Control, { base.OnAttachedToLogicalTree(e); _tokenBindingsDisposable = new CompositeDisposable(); - - this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, MarginToAnchorProperty, SharedTokenKey.MarginXXS)); - - BindUtils.RelayBind(this, AnchorTargetProperty, _flyoutStateHelper, FlyoutStateHelper.AnchorTargetProperty); - BindUtils.RelayBind(this, FlyoutProperty, _flyoutStateHelper, FlyoutStateHelper.FlyoutProperty); - BindUtils.RelayBind(this, MouseEnterDelayProperty, _flyoutStateHelper, - FlyoutStateHelper.MouseEnterDelayProperty); - BindUtils.RelayBind(this, MouseLeaveDelayProperty, _flyoutStateHelper, - FlyoutStateHelper.MouseLeaveDelayProperty); - BindUtils.RelayBind(this, TriggerProperty, _flyoutStateHelper, FlyoutStateHelper.TriggerTypeProperty); - SetupFlyoutProperties(); } protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) @@ -214,7 +203,16 @@ public class FlyoutHost : Control, protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); + BindUtils.RelayBind(this, AnchorTargetProperty, _flyoutStateHelper, FlyoutStateHelper.AnchorTargetProperty); + BindUtils.RelayBind(this, FlyoutProperty, _flyoutStateHelper, FlyoutStateHelper.FlyoutProperty); + BindUtils.RelayBind(this, MouseEnterDelayProperty, _flyoutStateHelper, + FlyoutStateHelper.MouseEnterDelayProperty); + BindUtils.RelayBind(this, MouseLeaveDelayProperty, _flyoutStateHelper, + FlyoutStateHelper.MouseLeaveDelayProperty); + BindUtils.RelayBind(this, TriggerProperty, _flyoutStateHelper, FlyoutStateHelper.TriggerTypeProperty); + SetupFlyoutProperties(); _flyoutStateHelper.NotifyAttachedToVisualTree(); + this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, MarginToAnchorProperty, SharedTokenKey.MarginXXS)); } protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) diff --git a/src/AtomUI.Controls/Input/TextBox.cs b/src/AtomUI.Controls/Input/TextBox.cs index d4884d1d8..bf15b13d8 100644 --- a/src/AtomUI.Controls/Input/TextBox.cs +++ b/src/AtomUI.Controls/Input/TextBox.cs @@ -113,12 +113,6 @@ public class TextBox : AvaloniaTextBox, this.RegisterResources(); } - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - SetupEffectiveShowClearButton(); - } - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); @@ -130,13 +124,11 @@ public class TextBox : AvaloniaTextBox, { SetupEffectiveShowClearButton(); } - - if (change.Property == StatusProperty) + else if (change.Property == StatusProperty) { UpdatePseudoClasses(); } - - if (change.Property == InnerLeftContentProperty || + else if (change.Property == InnerLeftContentProperty || change.Property == InnerRightContentProperty) { if (change.OldValue is Control oldControl) @@ -179,4 +171,10 @@ public class TextBox : AvaloniaTextBox, base.OnDetachedFromLogicalTree(e); this.DisposeTokenBindings(); } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + SetupEffectiveShowClearButton(); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/ListBox/ListBoxItem.cs b/src/AtomUI.Controls/ListBox/ListBoxItem.cs index f168909fd..4a77e3729 100644 --- a/src/AtomUI.Controls/ListBox/ListBoxItem.cs +++ b/src/AtomUI.Controls/ListBox/ListBoxItem.cs @@ -70,4 +70,10 @@ public class ListBoxItem : AvaloniaListBoxItem } } } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + SetupTransitions(); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Loading/LoadingIndicator.cs b/src/AtomUI.Controls/Loading/LoadingIndicator.cs index 02677bc95..241d53a06 100644 --- a/src/AtomUI.Controls/Loading/LoadingIndicator.cs +++ b/src/AtomUI.Controls/Loading/LoadingIndicator.cs @@ -7,11 +7,11 @@ using Avalonia; using Avalonia.Animation; using Avalonia.Animation.Easings; using Avalonia.Controls; +using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Media; using Avalonia.Media.Transformation; using Avalonia.Styling; -using Avalonia.VisualTree; namespace AtomUI.Controls; @@ -122,7 +122,7 @@ public class LoadingIndicator : TemplatedControl, get => _indicatorAngle; set => SetAndRaise(IndicatorAngleProperty, ref _indicatorAngle, value); } - + Control IControlSharedTokenResourcesHost.HostControl => this; string IControlSharedTokenResourcesHost.TokenId => LoadingIndicatorToken.ID; @@ -130,8 +130,8 @@ public class LoadingIndicator : TemplatedControl, private Animation? _animation; private TextBlock? _loadingText; - private Canvas? _mainContainer; private RenderInfo? _renderInfo; + private ContentPresenter? _customIndicatorIconPresenter; private CancellationTokenSource? _cancellationTokenSource; internal const double LARGE_INDICATOR_SIZE = 48; @@ -154,7 +154,7 @@ public class LoadingIndicator : TemplatedControl, { this.RegisterResources(); } - + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); @@ -173,60 +173,40 @@ public class LoadingIndicator : TemplatedControl, protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) { base.OnPropertyChanged(e); - if (this.IsAttachedToVisualTree()) + if (e.Property == CustomIndicatorIconProperty) { - if (e.Property == CustomIndicatorIconProperty) + if (e.OldValue is Icon oldIcon) { - var oldCustomIcon = e.GetOldValue(); - if (oldCustomIcon is not null) - { - _mainContainer?.Children.Remove(oldCustomIcon); - } + oldIcon.SetTemplatedParent(null); + } - SetupCustomIndicator(); + if (e.NewValue is Icon newIcon) + { + newIcon.SetTemplatedParent(this); } } - if (e.Property == IndicatorAngleProperty) { - if (CustomIndicatorIcon is not null) - { - HandleIndicatorAngleChanged(); - } + HandleIndicatorAngleChanged(); } } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); - HandleTemplateApplied(e.NameScope); - } - - private void HandleTemplateApplied(INameScope scope) - { - _mainContainer = scope.Find(LoadingIndicatorTheme.MainContainerPart); - _loadingText = scope.Find(LoadingIndicatorTheme.LoadingTextPart); - - SetupCustomIndicator(); + _loadingText = e.NameScope.Find(LoadingIndicatorTheme.LoadingTextPart); + _customIndicatorIconPresenter = + e.NameScope.Find(LoadingIndicatorTheme.CustomIndicatorIconPresenterPart); } // 只在使用自定义的 Icon 的时候有效 private void HandleIndicatorAngleChanged() { - if (CustomIndicatorIcon is not null) + if (_customIndicatorIconPresenter is not null && _customIndicatorIconPresenter.IsVisible) { var builder = new TransformOperations.Builder(1); builder.AppendRotate(MathUtils.Deg2Rad(IndicatorAngle)); - CustomIndicatorIcon.RenderTransform = builder.Build(); - } - } - - private void SetupCustomIndicator() - { - if (CustomIndicatorIcon is not null) - { - CustomIndicatorIcon.SetTemplatedParent(this); - _mainContainer?.Children.Insert(0, CustomIndicatorIcon); + _customIndicatorIconPresenter.RenderTransform = builder.Build(); } } diff --git a/src/AtomUI.Controls/Loading/LoadingIndicatorTheme.cs b/src/AtomUI.Controls/Loading/LoadingIndicatorTheme.cs index d379990e2..7fa794da2 100644 --- a/src/AtomUI.Controls/Loading/LoadingIndicatorTheme.cs +++ b/src/AtomUI.Controls/Loading/LoadingIndicatorTheme.cs @@ -3,8 +3,11 @@ using AtomUI.Theme; using AtomUI.Theme.Styling; using Avalonia.Animation.Easings; using Avalonia.Controls; +using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; +using Avalonia.Data; +using Avalonia.Data.Converters; using Avalonia.Layout; using Avalonia.Styling; @@ -15,6 +18,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme { public const string MainContainerPart = "PART_MainContainer"; public const string LoadingTextPart = "PART_LoadingText"; + public const string CustomIndicatorIconPresenterPart = "PART_CustomIndicatorIconPresenter"; public LoadingIndicatorTheme() : base(typeof(LoadingIndicator)) @@ -25,6 +29,17 @@ internal class LoadingIndicatorTheme : BaseControlTheme { return new FuncControlTemplate((indicator, scope) => { + var customIndicatorIconPresenter = new ContentPresenter() + { + Name = CustomIndicatorIconPresenterPart, + }; + CreateTemplateParentBinding(customIndicatorIconPresenter, ContentPresenter.ContentProperty, + LoadingIndicator.CustomIndicatorIconProperty); + CreateTemplateParentBinding(customIndicatorIconPresenter, ContentPresenter.IsVisibleProperty, + LoadingIndicator.CustomIndicatorIconProperty, + BindingMode.Default, + ObjectConverters.IsNotNull); + customIndicatorIconPresenter.RegisterInNameScope(scope); var loadingText = new TextBlock() { Name = LoadingTextPart, @@ -37,6 +52,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme { Name = MainContainerPart }; + mainContainer.Children.Add(customIndicatorIconPresenter); mainContainer.Children.Add(loadingText); mainContainer.RegisterInNameScope(scope); return mainContainer; @@ -49,7 +65,8 @@ internal class LoadingIndicatorTheme : BaseControlTheme commonStyle.Add(Layoutable.HorizontalAlignmentProperty, HorizontalAlignment.Left); commonStyle.Add(Layoutable.VerticalAlignmentProperty, VerticalAlignment.Top); commonStyle.Add(TemplatedControl.FontSizeProperty, SharedTokenKey.FontSize); - commonStyle.Add(LoadingIndicator.MotionEasingCurveProperty, new SetterValueFactory(() => new LinearEasing())); + commonStyle.Add(LoadingIndicator.MotionEasingCurveProperty, + new SetterValueFactory(() => new LinearEasing())); commonStyle.Add(LoadingIndicator.MotionDurationProperty, LoadingIndicatorTokenKey.IndicatorDuration); commonStyle.Add(LoadingIndicator.DotBgBrushProperty, SharedTokenKey.ColorPrimary); commonStyle.Add(LoadingIndicator.IndicatorTextMarginProperty, SharedTokenKey.MarginXXS); @@ -63,7 +80,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme private void BuildCustomIconStyle() { - var customIconStyle = new Style(selector => selector.Nesting().Template().OfType()); + var customIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType()); customIconStyle.Add(Icon.IconModeProperty, IconMode.Normal); customIconStyle.Add(Layoutable.VerticalAlignmentProperty, VerticalAlignment.Center); customIconStyle.Add(Layoutable.HorizontalAlignmentProperty, HorizontalAlignment.Center); @@ -71,7 +88,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme var largeSizeStyle = new Style(selector => selector.Nesting().PropertyEquals(LoadingIndicator.SizeTypeProperty, SizeType.Large)); - var largeIconStyle = new Style(selector => selector.Nesting().Template().OfType()); + var largeIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType()); largeIconStyle.Add(Layoutable.WidthProperty, LoadingIndicator.LARGE_INDICATOR_SIZE); largeIconStyle.Add(Layoutable.HeightProperty, LoadingIndicator.LARGE_INDICATOR_SIZE); largeSizeStyle.Add(largeIconStyle); @@ -79,7 +96,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme var middleSizeStyle = new Style(selector => selector.Nesting().PropertyEquals(LoadingIndicator.SizeTypeProperty, SizeType.Middle)); - var middleIconStyle = new Style(selector => selector.Nesting().Template().OfType()); + var middleIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType()); middleIconStyle.Add(Layoutable.WidthProperty, LoadingIndicator.MIDDLE_INDICATOR_SIZE); middleIconStyle.Add(Layoutable.HeightProperty, LoadingIndicator.MIDDLE_INDICATOR_SIZE); middleSizeStyle.Add(middleIconStyle); @@ -87,7 +104,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme var smallSizeStyle = new Style(selector => selector.Nesting().PropertyEquals(LoadingIndicator.SizeTypeProperty, SizeType.Small)); - var smallIconStyle = new Style(selector => selector.Nesting().Template().OfType()); + var smallIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType()); smallIconStyle.Add(Layoutable.WidthProperty, LoadingIndicator.SMALL_INDICATOR_SIZE); smallIconStyle.Add(Layoutable.HeightProperty, LoadingIndicator.SMALL_INDICATOR_SIZE); smallSizeStyle.Add(smallIconStyle);