enhance: avalonia TextBox demo.

This commit is contained in:
NaBian committed 2025-08-03 16:14:35 +08:00
1 parent 5f2cbeab9d
commit f9982820a9
7 files changed
+208 -129

No files matched your search

@@ -24,11 +24,8 @@
[ "DataGrid", "DataGridDemo", "Brush.DataGrid", "", "" ],
[ "TreeView", "TreeViewDemo", "Brush.TreeView", "", "" ],
[ "ListBox", "ListBoxDemo", "Brush.ListBox", "", "" ],
[ "ListView", "ListViewDemo", "Brush.ListView", "", "" ],
[ "GroupBox", "GroupBoxDemo", "Brush.GroupBox", "", "" ],
[ "Menu", "MenuDemo", "Brush.ContextMenu", "", "" ],
[ "RichTextBox", "RichTextBoxDemo", "Brush.RichTextBox", "", "" ],
[ "FlowDocument", "FlowDocumentDemo", "Brush.WPFFlowDocument", "", "" ],
[ "ToolBar", "ToolBarDemo", "Brush.ToolBar", "", "" ],
[ "Border", "BorderDemo", "Brush.BorderElement", "", "" ],
[ "Label", "LabelDemo", "Brush.Label", "", "" ],
@@ -121,7 +118,7 @@
"group": false,
"demoItemList": [
[ "HatchBrushGenerator", "HatchBrushGeneratorDemo", "Brush.DataGenerator", "", "" ],
[ "Morphing_Animation", "GeometryAnimationDemo", "Brush.Animation", "", "" ],
[ "MorphingAnimation", "GeometryAnimationDemo", "Brush.Animation", "", "" ],
[ "Effects", "EffectsDemo", "Brush.Effects", "", "" ]
]
}
@@ -21,6 +21,11 @@
Theme="{StaticResource TextBoxExtend}"
Margin="0,32,0,0"
Text="This is the content" />
<TextBox hc:TitleElement.Title="This is the title"
hc:InfoElement.ShowClearButton="True"
Theme="{StaticResource TextBoxExtend}"
Margin="0,32,0,0"
Text="This is the content" />
<TextBox hc:TitleElement.Title="This is the title"
Theme="{StaticResource TextBoxExtend}"
Margin="0,16,0,0"
@@ -59,6 +64,11 @@
Theme="{StaticResource TextBoxExtend.Small}"
Margin="0,32,0,0"
Text="This is the content" />
<TextBox hc:TitleElement.Title="This is the title"
hc:InfoElement.ShowClearButton="True"
Theme="{StaticResource TextBoxExtend.Small}"
Margin="0,32,0,0"
Text="This is the content" />
<TextBox hc:TitleElement.Title="This is the title"
Theme="{StaticResource TextBoxExtend.Small}"
Margin="0,16,0,0"
@@ -10,6 +10,7 @@
<hc:CornerRadiusSplitConverter x:Key="CornerRadiusSplitConverter" />
<hc:DoubleExpandConverter x:Key="DoubleExpandConverter" />
<hc:Double2GridLengthConverter x:Key="Double2GridLengthConverter" />
<hc:ThicknessSplitConverter x:Key="ThicknessSplitConverter" />
<avalonia:StringFormatConverter x:Key="StringFormatConverter" />
<avalonia:MarginMultiplierConverter x:Key="LeftMarginConverter"
Indent="16"
@@ -121,50 +121,77 @@
TextTrimming="CharacterEllipsis"
Text="{Binding Path=(hc:TitleElement.Title), RelativeSource={RelativeSource TemplatedParent}}" />
</DockPanel>
<Border x:Name="border"
Grid.Row="1"
CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" />
<TextBlock Grid.Row="1"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
IsVisible="{TemplateBinding Text, Converter={x:Static StringConverters.IsNullOrEmpty}}"
HorizontalAlignment="Stretch"
Theme="{StaticResource TextBlockDefaultThiLight}"
Text="{TemplateBinding Watermark}" />
<ScrollViewer Name="PART_ScrollViewer"
Grid.Row="1"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"
BringIntoViewOnFocusChange="{TemplateBinding (ScrollViewer.BringIntoViewOnFocusChange)}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<TextPresenter Name="PART_TextPresenter"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
CaretBlinkInterval="{TemplateBinding CaretBlinkInterval}"
CaretBrush="{TemplateBinding CaretBrush}"
CaretIndex="{TemplateBinding CaretIndex}"
LineHeight="{TemplateBinding LineHeight}"
LetterSpacing="{TemplateBinding LetterSpacing}"
PasswordChar="{TemplateBinding PasswordChar}"
RevealPassword="{TemplateBinding RevealPassword}"
SelectionBrush="{TemplateBinding SelectionBrush}"
SelectionEnd="{TemplateBinding SelectionEnd}"
SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}"
SelectionStart="{TemplateBinding SelectionStart}"
Text="{TemplateBinding Text,Mode=TwoWay}"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}" />
<ScrollViewer.Styles>
<Style Selector="ScrollContentPresenter#PART_ContentPresenter">
<Setter Property="Cursor"
Value="IBeam" />
</Style>
</ScrollViewer.Styles>
</ScrollViewer>
<Grid Grid.Row="1"
ColumnDefinitions="*,Auto">
<Border x:Name="border"
Grid.ColumnSpan="2"
CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" />
<TextBlock Grid.Column="0"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
IsVisible="{TemplateBinding Text, Converter={x:Static StringConverters.IsNullOrEmpty}}"
HorizontalAlignment="Stretch"
Theme="{StaticResource TextBlockDefaultThiLight}"
Text="{TemplateBinding Watermark}" />
<ScrollViewer Grid.Column="0"
Name="PART_ScrollViewer"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"
BringIntoViewOnFocusChange="{TemplateBinding (ScrollViewer.BringIntoViewOnFocusChange)}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<TextPresenter Name="PART_TextPresenter"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
CaretBlinkInterval="{TemplateBinding CaretBlinkInterval}"
CaretBrush="{TemplateBinding CaretBrush}"
CaretIndex="{TemplateBinding CaretIndex}"
LineHeight="{TemplateBinding LineHeight}"
LetterSpacing="{TemplateBinding LetterSpacing}"
PasswordChar="{TemplateBinding PasswordChar}"
RevealPassword="{TemplateBinding RevealPassword}"
SelectionBrush="{TemplateBinding SelectionBrush}"
SelectionEnd="{TemplateBinding SelectionEnd}"
SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}"
SelectionStart="{TemplateBinding SelectionStart}"
Text="{TemplateBinding Text,Mode=TwoWay}"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}" />
<ScrollViewer.Styles>
<Style Selector="ScrollContentPresenter#PART_ContentPresenter">
<Setter Property="Cursor"
Value="IBeam" />
</Style>
</ScrollViewer.Styles>
</ScrollViewer>
<Button HorizontalContentAlignment="Left"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
hc:IconElement.Width="14"
Command="{Binding $parent[TextBox].Clear}"
Name="ButtonClear"
Focusable="False"
Grid.Column="1"
Theme="{StaticResource ButtonIcon}"
Padding="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ThicknessSplitConverter}, ConverterParameter='0,0,1,0'}"
hc:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}"
Foreground="{Binding BorderBrush,ElementName=border}">
<Button.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="IsPointerOver" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="(hc:InfoElement.ShowClearButton)" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="IsReadOnly"
Converter="{x:Static BoolConverters.Not}" />
</MultiBinding>
</Button.IsVisible>
</Button>
</Grid>
</Grid>
</ControlTemplate>
@@ -191,50 +218,77 @@
TextTrimming="CharacterEllipsis"
Text="{Binding Path=(hc:TitleElement.Title), RelativeSource={RelativeSource TemplatedParent}}" />
</DockPanel>
<Border x:Name="border"
Grid.Column="1"
CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" />
<TextBlock Grid.Column="1"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
IsVisible="{TemplateBinding Text, Converter={x:Static StringConverters.IsNullOrEmpty}}"
HorizontalAlignment="Stretch"
Theme="{StaticResource TextBlockDefaultThiLight}"
Text="{TemplateBinding Watermark}" />
<ScrollViewer Name="PART_ScrollViewer"
Grid.Column="1"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"
BringIntoViewOnFocusChange="{TemplateBinding (ScrollViewer.BringIntoViewOnFocusChange)}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<TextPresenter Name="PART_TextPresenter"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
CaretBlinkInterval="{TemplateBinding CaretBlinkInterval}"
CaretBrush="{TemplateBinding CaretBrush}"
CaretIndex="{TemplateBinding CaretIndex}"
LineHeight="{TemplateBinding LineHeight}"
LetterSpacing="{TemplateBinding LetterSpacing}"
PasswordChar="{TemplateBinding PasswordChar}"
RevealPassword="{TemplateBinding RevealPassword}"
SelectionBrush="{TemplateBinding SelectionBrush}"
SelectionEnd="{TemplateBinding SelectionEnd}"
SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}"
SelectionStart="{TemplateBinding SelectionStart}"
Text="{TemplateBinding Text,Mode=TwoWay}"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}" />
<ScrollViewer.Styles>
<Style Selector="ScrollContentPresenter#PART_ContentPresenter">
<Setter Property="Cursor"
Value="IBeam" />
</Style>
</ScrollViewer.Styles>
</ScrollViewer>
<Grid Grid.Column="1"
ColumnDefinitions="*,Auto">
<Border x:Name="border"
Grid.ColumnSpan="2"
CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" />
<TextBlock Grid.Column="0"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
IsVisible="{TemplateBinding Text, Converter={x:Static StringConverters.IsNullOrEmpty}}"
HorizontalAlignment="Stretch"
Theme="{StaticResource TextBlockDefaultThiLight}"
Text="{TemplateBinding Watermark}" />
<ScrollViewer Grid.Column="0"
Name="PART_ScrollViewer"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"
BringIntoViewOnFocusChange="{TemplateBinding (ScrollViewer.BringIntoViewOnFocusChange)}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<TextPresenter Name="PART_TextPresenter"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
CaretBlinkInterval="{TemplateBinding CaretBlinkInterval}"
CaretBrush="{TemplateBinding CaretBrush}"
CaretIndex="{TemplateBinding CaretIndex}"
LineHeight="{TemplateBinding LineHeight}"
LetterSpacing="{TemplateBinding LetterSpacing}"
PasswordChar="{TemplateBinding PasswordChar}"
RevealPassword="{TemplateBinding RevealPassword}"
SelectionBrush="{TemplateBinding SelectionBrush}"
SelectionEnd="{TemplateBinding SelectionEnd}"
SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}"
SelectionStart="{TemplateBinding SelectionStart}"
Text="{TemplateBinding Text,Mode=TwoWay}"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}" />
<ScrollViewer.Styles>
<Style Selector="ScrollContentPresenter#PART_ContentPresenter">
<Setter Property="Cursor"
Value="IBeam" />
</Style>
</ScrollViewer.Styles>
</ScrollViewer>
<Button HorizontalContentAlignment="Left"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
hc:IconElement.Width="14"
Command="{Binding $parent[TextBox].Clear}"
Name="ButtonClear"
Focusable="False"
Grid.Column="1"
Theme="{StaticResource ButtonIcon}"
Padding="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ThicknessSplitConverter}, ConverterParameter='0,0,1,0'}"
hc:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}"
Foreground="{Binding BorderBrush,ElementName=border}">
<Button.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="IsPointerOver" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="(hc:InfoElement.ShowClearButton)" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="IsReadOnly"
Converter="{x:Static BoolConverters.Not}" />
</MultiBinding>
</Button.IsVisible>
</Button>
</Grid>
</Grid>
</ControlTemplate>
@@ -7,7 +7,7 @@ namespace HandyControl.Tools.Converter;
public class Double2GridLengthConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not double doubleValue)
{
@@ -22,7 +22,7 @@ public class Double2GridLengthConverter : IValueConverter
return new GridLength(doubleValue);
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
@@ -0,0 +1,36 @@
using System;
using System.Globalization;
using Avalonia;
using Avalonia.Data.Converters;
namespace HandyControl.Tools.Converter;
public class ThicknessSplitConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not Thickness thickness || parameter is not string str)
{
return value;
}
string[] arr = str.Split(',');
if (arr.Length != 4)
{
return thickness;
}
return new Thickness(
left: double.TryParse(arr[0], out double leftTimes) ? leftTimes * thickness.Left : thickness.Left,
top: double.TryParse(arr[1], out double topTimes) ? topTimes * thickness.Top : thickness.Top,
right: double.TryParse(arr[2], out double rightTimes) ? rightTimes * thickness.Right : thickness.Right,
bottom: double.TryParse(arr[3], out double bottomTimes) ? bottomTimes * thickness.Bottom : thickness.Bottom
);
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
@@ -9,43 +9,24 @@ public class ThicknessSplitConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Thickness thickness)
if (value is not Thickness thickness || parameter is not string str)
{
if (parameter is string str)
{
var arr = str.Split(',');
if (arr.Length != 4)
{
return thickness;
}
var result = new Thickness(thickness.Left, thickness.Top, thickness.Right, thickness.Bottom);
if (double.TryParse(arr[0], out double leftTimes))
{
result.Left = leftTimes * thickness.Left;
}
if (double.TryParse(arr[1], out double topTimes))
{
result.Top = topTimes * thickness.Top;
}
if (double.TryParse(arr[2], out double rightTimes))
{
result.Right = rightTimes * thickness.Right;
}
if (double.TryParse(arr[3], out double bottomTimes))
{
result.Bottom = bottomTimes * thickness.Bottom;
}
return result;
}
return value;
}
return value;
var arr = str.Split(',');
if (arr.Length != 4)
{
return thickness;
}
return new Thickness(
left: double.TryParse(arr[0], out double leftTimes) ? leftTimes * thickness.Left : thickness.Left,
top: double.TryParse(arr[1], out double topTimes) ? topTimes * thickness.Top : thickness.Top,
right: double.TryParse(arr[2], out double rightTimes) ? rightTimes * thickness.Right : thickness.Right,
bottom: double.TryParse(arr[3], out double bottomTimes) ? bottomTimes * thickness.Bottom : thickness.Bottom
);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)