mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-29 18:38:16 +08:00
完成 Popup 菜单分割控件
This commit is contained in:
parent
198a40617c
commit
44d61f86b5
@ -23,6 +23,9 @@
|
||||
<PackageVersion Include="xunit.extensibility.execution" Version="2.8.0" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.0" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.1.0" />
|
||||
<!-- 开发支持 -->
|
||||
|
||||
<PackageVersion Include="Nlnet.Avalonia.DevTools" Version="1.0.1-beta.22" />
|
||||
|
||||
<!-- 源码生成 -->
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0-3.final" />
|
||||
|
@ -24,6 +24,7 @@
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" />
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" />
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Nlnet.Avalonia.DevTools" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -3,6 +3,7 @@ using AtomUI.Icon.AntDesign;
|
||||
using Avalonia;
|
||||
using Avalonia.Dialogs;
|
||||
using Avalonia.Media;
|
||||
using Nlnet.Avalonia.DevTools;
|
||||
|
||||
namespace AtomUI.Demo.Desktop;
|
||||
|
||||
@ -30,6 +31,7 @@ class Program
|
||||
.UseManagedSystemDialogs()
|
||||
.UsePlatformDetect()
|
||||
.UseAtomUI()
|
||||
.UseDevToolsForAvalonia()
|
||||
.UseIconPackage<AntDesignIconPackage>(true)
|
||||
.With(new Win32PlatformOptions())
|
||||
.LogToTrace();
|
||||
|
@ -126,6 +126,8 @@ public class Alert : TemplatedControl, IControlCustomStyle
|
||||
_customStyle.HandleTemplateApplied(e.NameScope);
|
||||
}
|
||||
|
||||
#region IControlCustomStyle 实现
|
||||
|
||||
void IControlCustomStyle.HandleTemplateApplied(INameScope scope)
|
||||
{
|
||||
BindUtils.CreateTokenBinding(this, BorderThicknessProperty, GlobalResourceKey.BorderThickness,
|
||||
@ -133,8 +135,6 @@ public class Alert : TemplatedControl, IControlCustomStyle
|
||||
new RenderScaleAwareThicknessConfigure(this));
|
||||
SetupCloseButton();
|
||||
}
|
||||
|
||||
#region IControlCustomStyle 实现
|
||||
|
||||
void IControlCustomStyle.HandlePropertyChangedForStyle(AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
|
@ -118,15 +118,14 @@ namespace AtomUI.Styling
|
||||
{
|
||||
public static readonly TokenResourceKey MenuPopupBorderRadius = new TokenResourceKey("Menu.MenuPopupBorderRadius");
|
||||
public static readonly TokenResourceKey MenuPopupBoxShadows = new TokenResourceKey("Menu.MenuPopupBoxShadows");
|
||||
public static readonly TokenResourceKey MenuPopupContentPadding = new TokenResourceKey("Menu.MenuPopupContentPadding");
|
||||
public static readonly TokenResourceKey MenuPopupMinWidth = new TokenResourceKey("Menu.MenuPopupMinWidth");
|
||||
public static readonly TokenResourceKey MenuPopupMaxWidth = new TokenResourceKey("Menu.MenuPopupMaxWidth");
|
||||
public static readonly TokenResourceKey MenuPopupMinHeight = new TokenResourceKey("Menu.MenuPopupMinHeight");
|
||||
public static readonly TokenResourceKey MenuPopupMaxHeight = new TokenResourceKey("Menu.MenuPopupMaxHeight");
|
||||
public static readonly TokenResourceKey MenuArrowSize = new TokenResourceKey("Menu.MenuArrowSize");
|
||||
public static readonly TokenResourceKey MenuArrowOffset = new TokenResourceKey("Menu.MenuArrowOffset");
|
||||
public static readonly TokenResourceKey MenuMargin = new TokenResourceKey("Menu.MenuMargin");
|
||||
public static readonly TokenResourceKey MenuTearOffHeight = new TokenResourceKey("Menu.MenuTearOffHeight");
|
||||
public static readonly TokenResourceKey MenuContentPadding = new TokenResourceKey("Menu.MenuContentPadding");
|
||||
public static readonly TokenResourceKey MenuBgColor = new TokenResourceKey("Menu.MenuBgColor");
|
||||
public static readonly TokenResourceKey ItemColor = new TokenResourceKey("Menu.ItemColor");
|
||||
public static readonly TokenResourceKey ItemHoverColor = new TokenResourceKey("Menu.ItemHoverColor");
|
||||
@ -159,6 +158,7 @@ namespace AtomUI.Styling
|
||||
public static readonly TokenResourceKey TopLevelItemLineHeightLG = new TokenResourceKey("Menu.TopLevelItemLineHeightLG");
|
||||
public static readonly TokenResourceKey TopLevelItemLineHeightSM = new TokenResourceKey("Menu.TopLevelItemLineHeightSM");
|
||||
public static readonly TokenResourceKey TopLevelItemPopupMarginToAnchor = new TokenResourceKey("Menu.TopLevelItemPopupMarginToAnchor");
|
||||
public static readonly TokenResourceKey SeparatorItemHeight = new TokenResourceKey("Menu.SeparatorItemHeight");
|
||||
}
|
||||
|
||||
public static class OptionButtonResourceKey
|
||||
|
@ -1,12 +1,28 @@
|
||||
using AtomUI.Styling;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
public class MenuItemTheme : ControlTheme
|
||||
internal class MenuItemTheme : ControlTheme
|
||||
{
|
||||
public MenuItemTheme()
|
||||
: base(typeof(MenuItem))
|
||||
{
|
||||
}
|
||||
|
||||
protected override IControlTemplate? BuildControlTemplate()
|
||||
{
|
||||
return new FuncControlTemplate<MenuItem>((item, scope) =>
|
||||
{
|
||||
return new Border()
|
||||
{
|
||||
Height = 30,
|
||||
Background = new SolidColorBrush(Colors.Chocolate),
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
@ -1,8 +1,42 @@
|
||||
namespace AtomUI.Controls;
|
||||
using AtomUI.Styling;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Metadata;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
using AvaloniaScrollViewer = Avalonia.Controls.ScrollViewer;
|
||||
|
||||
public class MenuScrollViewer : AvaloniaScrollViewer
|
||||
[TemplatePart(MenuScrollViewerTheme.ScrollDownButtonPart, typeof(IconButton))]
|
||||
[TemplatePart(MenuScrollViewerTheme.ScrollUpButtonPart, typeof(IconButton))]
|
||||
[TemplatePart(MenuScrollViewerTheme.ScrollViewContentPart, typeof(ScrollContentPresenter))]
|
||||
public class MenuScrollViewer : AvaloniaScrollViewer, IControlCustomStyle
|
||||
{
|
||||
private readonly IControlCustomStyle _customStyle;
|
||||
private IconButton? _scrollUpButton;
|
||||
private IconButton? _scrollDownButton;
|
||||
private ScrollContentPresenter? _scrollViewContent;
|
||||
|
||||
public MenuScrollViewer()
|
||||
{
|
||||
_customStyle = this;
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
_customStyle.HandleTemplateApplied(e.NameScope);
|
||||
}
|
||||
|
||||
#region IControlCustomStyle 实现
|
||||
|
||||
void IControlCustomStyle.HandleTemplateApplied(INameScope scope)
|
||||
{
|
||||
_scrollUpButton = scope.Find<IconButton>(MenuScrollViewerTheme.ScrollUpButtonPart);
|
||||
_scrollDownButton = scope.Find<IconButton>(MenuScrollViewerTheme.ScrollDownButtonPart);
|
||||
_scrollViewContent = scope.Find<ScrollContentPresenter>(MenuScrollViewerTheme.ScrollViewContentPart);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@ -1,12 +1,82 @@
|
||||
using AtomUI.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Input.GestureRecognizers;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
public class MenuScrollViewerTheme : ControlTheme
|
||||
internal class MenuScrollViewerTheme : ControlTheme
|
||||
{
|
||||
public const string ScrollUpButtonPart = "Part_ScrollUpButton";
|
||||
public const string ScrollDownButtonPart = "Part_ScrollDownButton";
|
||||
public const string ScrollViewContentPart = "PART_ContentPresenter";
|
||||
public const string MainContainerPart = "Part_MainContainer";
|
||||
|
||||
public MenuScrollViewerTheme()
|
||||
: base(typeof(MenuScrollViewer))
|
||||
: base(typeof(MenuScrollViewer)) { }
|
||||
|
||||
protected override IControlTemplate BuildControlTemplate()
|
||||
{
|
||||
return new FuncControlTemplate<MenuScrollViewer>((viewer, scope) =>
|
||||
{
|
||||
var dockPanel = new DockPanel();
|
||||
var scrollUpButton = new IconButton()
|
||||
{
|
||||
Name = ScrollUpButtonPart,
|
||||
};
|
||||
DockPanel.SetDock(scrollUpButton, Dock.Top);
|
||||
var scrollDownButton = new IconButton()
|
||||
{
|
||||
Name = ScrollDownButtonPart
|
||||
};
|
||||
DockPanel.SetDock(scrollDownButton, Dock.Bottom);
|
||||
|
||||
var scrollViewContent = CreateScrollContentPresenter(viewer);
|
||||
|
||||
dockPanel.Children.Add(scrollUpButton);
|
||||
dockPanel.Children.Add(scrollDownButton);
|
||||
dockPanel.Children.Add(scrollViewContent);
|
||||
scrollUpButton.RegisterInNameScope(scope);
|
||||
scrollDownButton.RegisterInNameScope(scope);
|
||||
scrollViewContent.RegisterInNameScope(scope);
|
||||
return dockPanel;
|
||||
});
|
||||
}
|
||||
|
||||
private ScrollContentPresenter CreateScrollContentPresenter(MenuScrollViewer viewer)
|
||||
{
|
||||
var scrollViewContent = new ScrollContentPresenter()
|
||||
{
|
||||
Name = ScrollViewContentPart
|
||||
};
|
||||
CreateTemplateParentBinding(scrollViewContent, ScrollContentPresenter.MarginProperty,
|
||||
MenuScrollViewer.PaddingProperty);
|
||||
CreateTemplateParentBinding(scrollViewContent, ScrollContentPresenter.HorizontalSnapPointsAlignmentProperty,
|
||||
MenuScrollViewer.HorizontalSnapPointsAlignmentProperty);
|
||||
CreateTemplateParentBinding(scrollViewContent, ScrollContentPresenter.HorizontalSnapPointsTypeProperty,
|
||||
MenuScrollViewer.HorizontalSnapPointsTypeProperty);
|
||||
CreateTemplateParentBinding(scrollViewContent, ScrollContentPresenter.VerticalSnapPointsAlignmentProperty,
|
||||
MenuScrollViewer.VerticalSnapPointsAlignmentProperty);
|
||||
CreateTemplateParentBinding(scrollViewContent, ScrollContentPresenter.VerticalSnapPointsTypeProperty,
|
||||
MenuScrollViewer.VerticalSnapPointsTypeProperty);
|
||||
var scrollGestureRecognizer = new ScrollGestureRecognizer();
|
||||
BindUtils.RelayBind(scrollViewContent, ScrollContentPresenter.CanHorizontallyScrollProperty, scrollGestureRecognizer,
|
||||
ScrollGestureRecognizer.CanHorizontallyScrollProperty);
|
||||
BindUtils.RelayBind(scrollViewContent, ScrollContentPresenter.CanVerticallyScrollProperty, scrollGestureRecognizer,
|
||||
ScrollGestureRecognizer.CanVerticallyScrollProperty);
|
||||
|
||||
CreateTemplateParentBinding(scrollGestureRecognizer, ScrollGestureRecognizer.IsScrollInertiaEnabledProperty,
|
||||
MenuScrollViewer.IsScrollInertiaEnabledProperty);
|
||||
scrollViewContent.GestureRecognizers.Add(scrollGestureRecognizer);
|
||||
|
||||
return scrollViewContent;
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,6 +1,16 @@
|
||||
namespace AtomUI.Controls;
|
||||
using Avalonia;
|
||||
using Avalonia.Media;
|
||||
|
||||
public class MenuSeparator
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
using AvaloniaSeparator = Avalonia.Controls.Separator;
|
||||
|
||||
public class MenuSeparator : AvaloniaSeparator
|
||||
{
|
||||
|
||||
public override void Render(DrawingContext context)
|
||||
{
|
||||
var linePen = new Pen(BorderBrush);
|
||||
var offsetY = Bounds.Height / 2.0;
|
||||
context.DrawLine(linePen, new Point(0, offsetY), new Point(Bounds.Right, offsetY));
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using AtomUI.Styling;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@ -9,4 +10,12 @@ public class MenuSeparatorTheme : ControlTheme
|
||||
: base(typeof(MenuSeparator))
|
||||
{
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
commonStyle.Add(MenuSeparator.MinHeightProperty, MenuResourceKey.SeparatorItemHeight);
|
||||
commonStyle.Add(MenuSeparator.BorderBrushProperty, GlobalResourceKey.ColorBorder);
|
||||
Add(commonStyle);
|
||||
}
|
||||
}
|
@ -53,8 +53,7 @@ public class MenuTheme : ControlTheme
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
commonStyle.Add(Menu.BackgroundProperty, GlobalResourceKey.ColorBgContainer);
|
||||
commonStyle.Add(Menu.PaddingProperty, new Thickness(0));
|
||||
commonStyle.Add(Menu.BackgroundProperty, MenuResourceKey.MenuBgColor);
|
||||
commonStyle.Add(Menu.BorderBrushProperty, GlobalResourceKey.ColorBorder);
|
||||
var largeSizeType = new Style(selector => selector.Nesting().PropertyEquals(Menu.SizeTypeProperty, SizeType.Large));
|
||||
largeSizeType.Add(Menu.MinHeightProperty, GlobalResourceKey.ControlHeightLG);
|
||||
|
@ -25,6 +25,11 @@ internal class MenuToken : AbstractControlDesignToken
|
||||
/// </summary>
|
||||
public BoxShadows MenuPopupBoxShadows { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单内容边距
|
||||
/// </summary>
|
||||
public Thickness MenuPopupContentPadding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单 Popup 最小宽度
|
||||
/// </summary>
|
||||
@ -55,22 +60,12 @@ internal class MenuToken : AbstractControlDesignToken
|
||||
/// </summary>
|
||||
public double MenuArrowOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单间距
|
||||
/// </summary>
|
||||
public Thickness MenuMargin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分离菜单项的高度,这个用于菜单中快捷功能的图标显示
|
||||
/// TODO 暂时还没实现,但是最终会实现
|
||||
/// </summary>
|
||||
public double MenuTearOffHeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单内容边距
|
||||
/// </summary>
|
||||
public double MenuContentPadding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 弹出框背景色
|
||||
/// </summary>
|
||||
@ -231,7 +226,11 @@ internal class MenuToken : AbstractControlDesignToken
|
||||
/// </summary>
|
||||
public double TopLevelItemPopupMarginToAnchor { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 菜单分割项的高度
|
||||
/// </summary>
|
||||
public double SeparatorItemHeight { get; set; }
|
||||
|
||||
internal override void CalculateFromAlias()
|
||||
{
|
||||
base.CalculateFromAlias();
|
||||
@ -271,13 +270,6 @@ internal class MenuToken : AbstractControlDesignToken
|
||||
ItemPaddingInline = new Thickness(padding);
|
||||
ItemIconSize = fontSize;
|
||||
ItemIconMarginInlineEnd = controlHeightSM - fontSize;
|
||||
MenuArrowSize = (fontSize / 7.0) * 5.0;
|
||||
MenuArrowOffset = MenuArrowSize * 0.5;
|
||||
MenuTearOffHeight = ItemHeight * 1.2; // 暂时这么定义吧
|
||||
MenuContentPadding = _globalToken.PaddingXXS / 2; // 先默认一个最小的内容间距
|
||||
MenuMargin = new Thickness(1);
|
||||
|
||||
MenuPopupBoxShadows = _globalToken.BoxShadowsSecondary;
|
||||
|
||||
TopLevelItemColor = colorNeutralToken.ColorText;
|
||||
TopLevelItemSelectedColor = colorNeutralToken.ColorTextSecondary;
|
||||
@ -322,5 +314,13 @@ internal class MenuToken : AbstractControlDesignToken
|
||||
MenuPopupMinHeight = ItemHeight * 3;
|
||||
MenuPopupMaxHeight = ItemHeight * 30;
|
||||
|
||||
SeparatorItemHeight = _globalToken.SeedToken.LineWidth * 5; // 上下两像素,留一像素给自己
|
||||
|
||||
MenuArrowSize = (fontSize / 7.0) * 5.0;
|
||||
MenuArrowOffset = MenuArrowSize * 0.5;
|
||||
MenuTearOffHeight = ItemHeight * 1.2; // 暂时这么定义吧
|
||||
|
||||
MenuPopupContentPadding = new Thickness(_globalToken.PaddingXXS, MenuPopupBorderRadius.TopLeft / 2);
|
||||
MenuPopupBoxShadows = _globalToken.BoxShadowsSecondary;
|
||||
}
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
using AtomUI.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
@ -19,6 +17,7 @@ public class TopLevelMenuItemTheme : ControlTheme
|
||||
|
||||
public const string PopupPart = "PART_Popup";
|
||||
public const string HeaderPresenterPart = "PART_HeaderPresenter";
|
||||
public const string ItemsPresenterPart = "PART_ItemsPresenter";
|
||||
|
||||
public TopLevelMenuItemTheme() : base(typeof(MenuItem)) {}
|
||||
|
||||
@ -59,6 +58,7 @@ public class TopLevelMenuItemTheme : ControlTheme
|
||||
|
||||
private Popup CreateMenuPopup(MenuItem menuItem)
|
||||
{
|
||||
|
||||
var popup = new Popup()
|
||||
{
|
||||
Name = PopupPart,
|
||||
@ -66,8 +66,31 @@ public class TopLevelMenuItemTheme : ControlTheme
|
||||
IsLightDismissEnabled = true,
|
||||
Placement = PlacementMode.BottomEdgeAlignedLeft,
|
||||
OverlayInputPassThroughElement = menuItem,
|
||||
Child = new Border()
|
||||
};
|
||||
|
||||
var border = new Border();
|
||||
BindUtils.CreateTokenBinding(border, Border.BackgroundProperty, GlobalResourceKey.ColorBgContainer);
|
||||
BindUtils.CreateTokenBinding(border, Border.CornerRadiusProperty, MenuResourceKey.MenuPopupBorderRadius);
|
||||
BindUtils.CreateTokenBinding(border, Border.MinWidthProperty, MenuResourceKey.MenuPopupMinWidth);
|
||||
BindUtils.CreateTokenBinding(border, Border.MaxWidthProperty, MenuResourceKey.MenuPopupMaxWidth);
|
||||
BindUtils.CreateTokenBinding(border, Border.MinHeightProperty, MenuResourceKey.MenuPopupMinHeight);
|
||||
BindUtils.CreateTokenBinding(border, Border.MaxHeightProperty, MenuResourceKey.MenuPopupMaxHeight);
|
||||
BindUtils.CreateTokenBinding(border, Border.PaddingProperty, MenuResourceKey.MenuPopupContentPadding);
|
||||
|
||||
var scrollViewer = new MenuScrollViewer();
|
||||
var itemsPresenter = new ItemsPresenter()
|
||||
{
|
||||
Name = ItemsPresenterPart,
|
||||
};
|
||||
CreateTemplateParentBinding(itemsPresenter, ItemsPresenter.ItemsPanelProperty, MenuItem.ItemsPanelProperty);
|
||||
Grid.SetIsSharedSizeScope(itemsPresenter, true);
|
||||
scrollViewer.Content = itemsPresenter;
|
||||
border.Child = scrollViewer;
|
||||
popup.Child = border;
|
||||
|
||||
BindUtils.CreateTokenBinding(popup, Popup.MarginToAnchorProperty, MenuResourceKey.TopLevelItemPopupMarginToAnchor);
|
||||
BindUtils.CreateTokenBinding(popup, Popup.MaskShadowsProperty, MenuResourceKey.MenuPopupBoxShadows);
|
||||
|
||||
CreateTemplateParentBinding(popup, Popup.IsOpenProperty, MenuItem.IsSubMenuOpenProperty, BindingMode.TwoWay);
|
||||
return popup;
|
||||
}
|
||||
@ -77,7 +100,6 @@ public class TopLevelMenuItemTheme : ControlTheme
|
||||
BuildCommonStyle();
|
||||
BuildSizeTypeStyle();
|
||||
BuildDisabledStyle();
|
||||
BuildPopupStyle();
|
||||
}
|
||||
|
||||
private void BuildCommonStyle()
|
||||
@ -132,25 +154,6 @@ public class TopLevelMenuItemTheme : ControlTheme
|
||||
Add(smallSizeStyle);
|
||||
}
|
||||
|
||||
private void BuildPopupStyle()
|
||||
{
|
||||
var popupStyle = new Style(selector => selector.Nesting().Template().OfType<Popup>());
|
||||
|
||||
popupStyle.Add(Popup.MarginToAnchorProperty, MenuResourceKey.TopLevelItemPopupMarginToAnchor);
|
||||
popupStyle.Add(Popup.MaskShadowsProperty, MenuResourceKey.MenuPopupBoxShadows);
|
||||
|
||||
Add(popupStyle);
|
||||
|
||||
var borderStyle = new Style(selector => selector.Nesting().Template().OfType<Popup>().Child().OfType<Border>());
|
||||
borderStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorBgContainer);
|
||||
borderStyle.Add(Border.CornerRadiusProperty, MenuResourceKey.MenuPopupBorderRadius);
|
||||
borderStyle.Add(Border.MinWidthProperty, MenuResourceKey.MenuPopupMinWidth);
|
||||
borderStyle.Add(Border.MaxWidthProperty, MenuResourceKey.MenuPopupMaxWidth);
|
||||
borderStyle.Add(Border.MinHeightProperty, MenuResourceKey.MenuPopupMinHeight);
|
||||
borderStyle.Add(Border.MaxHeightProperty, MenuResourceKey.MenuPopupMaxHeight);
|
||||
Add(borderStyle);
|
||||
}
|
||||
|
||||
private void BuildDisabledStyle()
|
||||
{
|
||||
var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
|
||||
|
@ -7,14 +7,14 @@ using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Markup.Xaml.Templates;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Metadata;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
using AvaloniaSeparator = Avalonia.Controls.Separator;
|
||||
|
||||
public enum SeparatorTitlePosition
|
||||
{
|
||||
Left,
|
||||
@ -22,7 +22,7 @@ public enum SeparatorTitlePosition
|
||||
Center
|
||||
}
|
||||
|
||||
public partial class Separator : TemplatedControl, IControlCustomStyle
|
||||
public class Separator : AvaloniaSeparator, IControlCustomStyle
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
|
@ -10,7 +10,7 @@ namespace AtomUI.Controls;
|
||||
[ControlThemeProvider]
|
||||
internal class SeparatorTheme : ControlTheme
|
||||
{
|
||||
public const string TitlePart = "PART_CloseBtn";
|
||||
public const string TitlePart = "PART_Title";
|
||||
|
||||
public SeparatorTheme()
|
||||
: base(typeof(Separator)) { }
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
@ -11,9 +10,9 @@ using AvaloniaControlTheme = Avalonia.Styling.ControlTheme;
|
||||
|
||||
public class ControlTheme : AvaloniaControlTheme
|
||||
{
|
||||
public ControlTheme() {}
|
||||
public ControlTheme(Type targetType) : base(targetType) {}
|
||||
|
||||
public ControlTheme() { }
|
||||
public ControlTheme(Type targetType) : base(targetType) { }
|
||||
|
||||
public void Build()
|
||||
{
|
||||
NotifyPreBuild();
|
||||
@ -22,6 +21,7 @@ public class ControlTheme : AvaloniaControlTheme
|
||||
if (template is not null) {
|
||||
Add(new Setter(TemplatedControl.TemplateProperty, template));
|
||||
}
|
||||
|
||||
NotifyBuildCompleted();
|
||||
}
|
||||
|
||||
@ -30,24 +30,52 @@ public class ControlTheme : AvaloniaControlTheme
|
||||
return default;
|
||||
}
|
||||
|
||||
protected virtual IControlTemplate? BuildControlTemplate() { return default; }
|
||||
protected virtual void BuildStyles() {}
|
||||
protected virtual void NotifyPreBuild() {}
|
||||
protected virtual void NotifyBuildCompleted() {}
|
||||
protected virtual IControlTemplate? BuildControlTemplate()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
protected static IDisposable CreateTemplateParentBinding(Control control, AvaloniaProperty property, string templateParentPath,
|
||||
protected virtual void BuildStyles() { }
|
||||
protected virtual void NotifyPreBuild() { }
|
||||
protected virtual void NotifyBuildCompleted() { }
|
||||
|
||||
protected static IDisposable CreateTemplateParentBinding(AvaloniaObject target, AvaloniaProperty property,
|
||||
string templateParentPath,
|
||||
BindingMode mode = BindingMode.Default)
|
||||
{
|
||||
return control.Bind(property, new Binding(templateParentPath)
|
||||
return target.Bind(property, new Binding(templateParentPath)
|
||||
{
|
||||
RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent),
|
||||
Mode = mode
|
||||
});
|
||||
}
|
||||
|
||||
protected static IDisposable CreateTemplateParentBinding(Control control, AvaloniaProperty property, AvaloniaProperty templateParentProperty,
|
||||
|
||||
protected static IDisposable CreateTemplateParentBinding<T>(AvaloniaObject target, StyledProperty<T> property,
|
||||
string templateParentPath,
|
||||
BindingMode mode = BindingMode.Default)
|
||||
{
|
||||
return target.Bind(property, new Binding(templateParentPath)
|
||||
{
|
||||
RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent),
|
||||
Mode = mode
|
||||
});
|
||||
}
|
||||
|
||||
protected static IDisposable CreateTemplateParentBinding<T>(AvaloniaObject target, DirectPropertyBase<T> property,
|
||||
string templateParentPath,
|
||||
BindingMode mode = BindingMode.Default)
|
||||
{
|
||||
return target.Bind(property, new Binding(templateParentPath)
|
||||
{
|
||||
RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent),
|
||||
Mode = mode
|
||||
});
|
||||
}
|
||||
|
||||
protected static IDisposable CreateTemplateParentBinding(AvaloniaObject target, AvaloniaProperty property,
|
||||
AvaloniaProperty templateParentProperty,
|
||||
BindingMode mode = BindingMode.Default)
|
||||
{
|
||||
return CreateTemplateParentBinding(control, property, templateParentProperty.Name, mode);
|
||||
return CreateTemplateParentBinding(target, property, templateParentProperty.Name, mode);
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ public static class BindUtils
|
||||
{
|
||||
public static IDisposable RelayBind(AvaloniaObject source, AvaloniaProperty sourceProperty, AvaloniaObject target,
|
||||
AvaloniaProperty? targetProperty = null,
|
||||
BindingMode mode = BindingMode.OneWay)
|
||||
BindingMode mode = BindingMode.Default)
|
||||
{
|
||||
targetProperty ??= sourceProperty;
|
||||
var registry = AvaloniaPropertyRegistry.Instance;
|
||||
|
Loading…
Reference in New Issue
Block a user