mirror of
https://gitee.com/chinware/atomui.git
synced 2024-12-02 03:47:52 +08:00
完成搜索类型的输入框
完成搜索类型的输入框
This commit is contained in:
parent
2d33d56823
commit
fed4c18c15
@ -104,5 +104,33 @@
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="Search box"
|
||||
Description="Example of creating a search box by grouping a standard input with a search button.">
|
||||
<StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0">
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left"/>
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonText="Search"/>
|
||||
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/>
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/>
|
||||
|
||||
<atom:SearchEdit Watermark="input search text"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SearchButtonStyle="Primary"
|
||||
SearchButtonText="Search"
|
||||
IsEnableClearButton="True"
|
||||
SizeType="Large"/>
|
||||
<atom:SearchEdit Watermark="input search text"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SearchButtonStyle="Primary"
|
||||
SearchButtonText="搜索一下"
|
||||
InnerRightContent="{atom:IconProvider Kind=AudioOutlined, NormalFilledColor=#1677ff, Width=16, Height=16}"
|
||||
IsEnableClearButton="True"
|
||||
SizeType="Large"/>
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
</showcase:ShowCasePanel>
|
||||
</UserControl>
|
@ -1,4 +1,5 @@
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Icon;
|
||||
using AtomUI.Media;
|
||||
using AtomUI.Theme.Data;
|
||||
@ -63,6 +64,9 @@ public class Button : AvaloniaButton, ISizeTypeAware, IControlCustomStyle, IWave
|
||||
public static readonly StyledProperty<string?> TextProperty
|
||||
= AvaloniaProperty.Register<Button, string?>(nameof(Text));
|
||||
|
||||
public static readonly StyledProperty<bool> IsIconVisibleProperty
|
||||
= AvaloniaProperty.Register<Button, bool>(nameof (IsIconVisible), true);
|
||||
|
||||
public ButtonType ButtonType
|
||||
{
|
||||
get => GetValue(ButtonTypeProperty);
|
||||
@ -105,6 +109,12 @@ public class Button : AvaloniaButton, ISizeTypeAware, IControlCustomStyle, IWave
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public bool IsIconVisible
|
||||
{
|
||||
get => GetValue(IsIconVisibleProperty);
|
||||
set => SetValue(IsIconVisibleProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
@ -347,6 +357,7 @@ public class Button : AvaloniaButton, ISizeTypeAware, IControlCustomStyle, IWave
|
||||
if (Icon is not null) {
|
||||
if (_stackPanel is not null) {
|
||||
UIStructureUtils.SetTemplateParent(Icon, this);
|
||||
BindUtils.RelayBind(this, IsIconVisibleProperty, Icon, PathIcon.IsVisibleProperty);
|
||||
_stackPanel.Children.Insert(0, Icon);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ public class LineEdit : TextBox
|
||||
{
|
||||
public const string ErrorPC = ":error";
|
||||
public const string WarningPC = ":warning";
|
||||
|
||||
#region 功能属性定义
|
||||
|
||||
public static readonly StyledProperty<object?> LeftAddOnProperty =
|
||||
@ -172,9 +173,9 @@ public class LineEdit : TextBox
|
||||
|
||||
#endregion
|
||||
|
||||
private ContentPresenter? _leftAddOnPresenter;
|
||||
private ContentPresenter? _rightAddOnPresenter;
|
||||
private Border? _lineEditKernelDecorator;
|
||||
protected Control? _leftAddOnPresenter;
|
||||
protected Control? _rightAddOnPresenter;
|
||||
protected Border? _lineEditKernelDecorator;
|
||||
|
||||
|
||||
static LineEdit()
|
||||
@ -188,8 +189,8 @@ public class LineEdit : TextBox
|
||||
base.OnApplyTemplate(e);
|
||||
TokenResourceBinder.CreateGlobalResourceBinding(this, BorderThicknessProperty, GlobalResourceKey.BorderThickness,
|
||||
BindingPriority.Template, new RenderScaleAwareThicknessConfigure(this));
|
||||
_leftAddOnPresenter = e.NameScope.Find<ContentPresenter>(LineEditTheme.LeftAddOnPart);
|
||||
_rightAddOnPresenter = e.NameScope.Find<ContentPresenter>(LineEditTheme.RightAddOnPart);
|
||||
_leftAddOnPresenter = e.NameScope.Find<Control>(LineEditTheme.LeftAddOnPart);
|
||||
_rightAddOnPresenter = e.NameScope.Find<Control>(LineEditTheme.RightAddOnPart);
|
||||
_lineEditKernelDecorator = e.NameScope.Find<Border>(LineEditTheme.LineEditKernelDecoratorPart);
|
||||
SetupEditKernelCornerRadius();
|
||||
SetupEffectiveShowClearButton();
|
||||
@ -221,7 +222,9 @@ public class LineEdit : TextBox
|
||||
}
|
||||
|
||||
if (change.Property == InnerLeftContentProperty ||
|
||||
change.Property == InnerRightContentProperty) {
|
||||
change.Property == InnerRightContentProperty ||
|
||||
change.Property == LeftAddOnProperty ||
|
||||
change.Property == RightAddOnProperty) {
|
||||
if (change.OldValue is Control oldControl) {
|
||||
UIStructureUtils.SetTemplateParent(oldControl, null);
|
||||
}
|
||||
@ -255,6 +258,13 @@ public class LineEdit : TextBox
|
||||
|
||||
LeftAddOnBorderThickness = new Thickness(top: topThickness, right:0, bottom:bottomThickness, left: leftThickness);
|
||||
RightAddOnBorderThickness = new Thickness(top: topThickness, right:rightThickness, bottom:bottomThickness, left: 0);
|
||||
|
||||
NotifyAddOnBorderInfoCalculated();
|
||||
}
|
||||
|
||||
protected virtual void NotifyAddOnBorderInfoCalculated()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void SetupEditKernelCornerRadius()
|
||||
|
@ -32,6 +32,10 @@ internal class LineEditTheme : BaseControlTheme
|
||||
public const string LineEditKernelPart = "PART_LineEditKernel";
|
||||
public const string LineEditKernelDecoratorPart = "PART_LineEditKernelDecorator";
|
||||
|
||||
public const int NormalZIndex = 1000;
|
||||
public const int ActivatedZIndex = 2000;
|
||||
|
||||
public LineEditTheme(Type targetType) : base(targetType) { }
|
||||
public LineEditTheme() : base(typeof(LineEdit)) { }
|
||||
|
||||
protected override IControlTemplate? BuildControlTemplate()
|
||||
@ -108,7 +112,6 @@ internal class LineEditTheme : BaseControlTheme
|
||||
var kernelLayout = new LineEditKernel()
|
||||
{
|
||||
Name = LineEditKernelPart,
|
||||
ZIndex = 1000,
|
||||
Cursor = new Cursor(StandardCursorType.Ibeam)
|
||||
};
|
||||
|
||||
@ -356,6 +359,10 @@ internal class LineEditTheme : BaseControlTheme
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
commonStyle.Add(LineEdit.ForegroundProperty, GlobalResourceKey.ColorText);
|
||||
|
||||
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
commonStyle.Add(decoratorStyle);
|
||||
|
||||
// 输入框左右小组件的 margin 设置
|
||||
var leftInnerContentStyle = new Style(selector => selector.Nesting().Template().Name(LeftInnerContentPart));
|
||||
leftInnerContentStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.LeftInnerAddOnMargin);
|
||||
@ -398,6 +405,15 @@ internal class LineEditTheme : BaseControlTheme
|
||||
largeStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
{
|
||||
// 左右 AddOn icon 的大小
|
||||
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
|
||||
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeLG);
|
||||
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeLG);
|
||||
largeStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
largeStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSizeLG);
|
||||
largeStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightLG);
|
||||
largeStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadiusLG);
|
||||
@ -419,6 +435,15 @@ internal class LineEditTheme : BaseControlTheme
|
||||
middleStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
{
|
||||
// 左右 AddOn icon 的大小
|
||||
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
|
||||
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
middleStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
middleStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSize);
|
||||
middleStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeight);
|
||||
middleStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadius);
|
||||
@ -439,6 +464,16 @@ internal class LineEditTheme : BaseControlTheme
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingSM);
|
||||
smallStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
{
|
||||
// 左右 AddOn icon 的大小
|
||||
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
|
||||
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeSM);
|
||||
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeSM);
|
||||
smallStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
smallStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSizeSM);
|
||||
smallStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightSM);
|
||||
smallStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadiusSM);
|
||||
|
@ -1,6 +1,59 @@
|
||||
namespace AtomUI.Controls;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Data;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public enum SearchEditButtonStyle
|
||||
{
|
||||
Default,
|
||||
Primary
|
||||
}
|
||||
|
||||
public class SearchEdit : LineEdit
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
public static readonly StyledProperty<SearchEditButtonStyle> SearchButtonStyleProperty =
|
||||
AvaloniaProperty.Register<SearchEdit, SearchEditButtonStyle>(nameof(SearchButtonStyle), SearchEditButtonStyle.Default);
|
||||
|
||||
public static readonly StyledProperty<string> SearchButtonTextProperty =
|
||||
AvaloniaProperty.Register<SearchEdit, string>(nameof(SearchButtonText));
|
||||
|
||||
public SearchEditButtonStyle SearchButtonStyle
|
||||
{
|
||||
get => GetValue(SearchButtonStyleProperty);
|
||||
set => SetValue(SearchButtonStyleProperty, value);
|
||||
}
|
||||
|
||||
public object? SearchButtonText
|
||||
{
|
||||
get => GetValue(SearchButtonTextProperty);
|
||||
set => SetValue(SearchButtonTextProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private Rect? _originRect;
|
||||
|
||||
protected override void NotifyAddOnBorderInfoCalculated()
|
||||
{
|
||||
RightAddOnBorderThickness = BorderThickness;
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
var size = base.ArrangeOverride(finalSize);
|
||||
if (_originRect is null) {
|
||||
_originRect = _rightAddOnPresenter?.Bounds;
|
||||
}
|
||||
if (_rightAddOnPresenter is not null && _originRect.HasValue) {
|
||||
_rightAddOnPresenter.Arrange(_originRect.Value.Inflate(new Thickness(1, 0, 0, 0)));
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
85
src/AtomUI.Controls/Input/SearchEditTheme.cs
Normal file
85
src/AtomUI.Controls/Input/SearchEditTheme.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
internal class SearchEditTheme : LineEditTheme
|
||||
{
|
||||
public SearchEditTheme() : base(typeof(SearchEdit)) { }
|
||||
|
||||
protected override void BuildRightAddOn(Grid layout, INameScope scope)
|
||||
{
|
||||
var searchIcon = new PathIcon()
|
||||
{
|
||||
Kind = "SearchOutlined"
|
||||
};
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(searchIcon, PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorIcon);
|
||||
var rightAddOnContentPresenter = new Button()
|
||||
{
|
||||
Name = RightAddOnPart,
|
||||
Focusable = false,
|
||||
Icon = searchIcon
|
||||
};
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.ContentProperty,
|
||||
SearchEdit.RightAddOnProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.BorderThicknessProperty,
|
||||
SearchEdit.RightAddOnBorderThicknessProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.CornerRadiusProperty,
|
||||
SearchEdit.RightAddOnCornerRadiusProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.TextProperty,
|
||||
SearchEdit.SearchButtonTextProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.SizeTypeProperty,
|
||||
SearchEdit.SizeTypeProperty);
|
||||
|
||||
rightAddOnContentPresenter.RegisterInNameScope(scope);
|
||||
layout.Children.Add(rightAddOnContentPresenter);
|
||||
Grid.SetColumn(rightAddOnContentPresenter, 2);
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
base.BuildStyles();
|
||||
|
||||
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
Add(decoratorStyle);
|
||||
|
||||
var decoratorHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.FocusWithIn),
|
||||
selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.PointerOver)));
|
||||
decoratorHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
|
||||
Add(decoratorHoverOrFocusStyle);
|
||||
|
||||
var searchButtonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
searchButtonStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
Add(searchButtonStyle);
|
||||
|
||||
var searchButtonStyleHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.Pressed),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.PointerOver)));
|
||||
searchButtonStyleHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
|
||||
Add(searchButtonStyleHoverOrFocusStyle);
|
||||
|
||||
// Icon button
|
||||
var iconSearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Default));
|
||||
{
|
||||
var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
buttonStyle.Add(Button.IsIconVisibleProperty, true);
|
||||
buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Default);
|
||||
iconSearchButtonStyle.Add(buttonStyle);
|
||||
}
|
||||
Add(iconSearchButtonStyle);
|
||||
|
||||
// primary button
|
||||
var primarySearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Primary));
|
||||
{
|
||||
var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
buttonStyle.Add(Button.IsIconVisibleProperty, false);
|
||||
buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Primary);
|
||||
primarySearchButtonStyle.Add(buttonStyle);
|
||||
}
|
||||
Add(primarySearchButtonStyle);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user