Open CodingOctocat opened 1 year ago
解决方案:此处的 root
元素建议改为:
<hc:SimplePanel x:Name="root"
Grid.Column="1">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}" />
<TextBlock Margin="{TemplateBinding Padding}"
HorizontalAlignment="Stretch"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Style="{StaticResource TextBlockDefaultThiLight}"
Text="{Binding Path=(hc:InfoElement.Placeholder), RelativeSource={RelativeSource TemplatedParent}}"
Visibility="{TemplateBinding Text,
Converter={StaticResource String2VisibilityReConverter}}" />
<ScrollViewer x:Name="PART_ContentHost"
Margin="-2,0,0,0"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
<Button Name="ButtonClear"
Width="Auto"
Height="Auto"
Padding="8,0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
hc:BorderElement.CornerRadius="4"
hc:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}"
hc:IconElement.Width="14"
Background="{TemplateBinding Background}"
Command="{x:Static hc:ControlCommands.Clear}"
Foreground="{Binding BorderBrush, ElementName=border}"
Style="{StaticResource ButtonIcon}"
Visibility="Collapsed" />
</hc:SimplePanel>
TextBoxPlusTopTemplate 、SearchBar(带 Clear 按钮) 及有类似实现的地方也需一并更改。
TopTemplate 中需要使用 hc:TitleElement.MarginOnTheTop
,但实际没有这个属性(#1498),暂时使用硬编码。
不使用两列的 Grid 还有一个好处,就是如果我使用 WrapPanel,当 TextBox 接近 WrapPanel 一行的宽度时,如果鼠标悬停在 TextBox 上面,那么 TextBox 会因为显示 Clear 按钮而变宽,导致换行,而换行后又失去鼠标悬停使得 Clear 按钮被隐藏折叠,TextBox 宽度减少而回退位置,循环往复,此效果如下:
SearchBar 带 Clear 按钮闪烁问题解决方案:
<ControlTemplate x:Key="SearchBarPlusTopTemplate"
TargetType="hc:SearchBar">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="{Binding Path=(hc:InfoElement.ContentHeight), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource Double2GridLengthConverter}}"
MinHeight="{Binding Path=(hc:InfoElement.MinContentHeight), RelativeSource={RelativeSource TemplatedParent}}" />
</Grid.RowDefinitions>
<DockPanel Margin="6,0,0,1"
HorizontalAlignment="{Binding Path=(hc:TitleElement.HorizontalAlignment), RelativeSource={RelativeSource TemplatedParent}}"
LastChildFill="True"
Visibility="{Binding Path=(hc:InfoElement.Title), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource String2VisibilityConverter}}">
<ContentPresenter Margin="4,0,0,0"
Content="{Binding Path=(hc:InfoElement.Symbol), RelativeSource={RelativeSource TemplatedParent}}"
DockPanel.Dock="Right"
TextElement.Foreground="{DynamicResource DangerBrush}"
Visibility="{Binding Path=(hc:InfoElement.Necessary), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource Boolean2VisibilityConverter}}" />
<TextBlock hc:TextBlockAttach.AutoTooltip="True"
Text="{Binding Path=(hc:InfoElement.Title), RelativeSource={RelativeSource TemplatedParent}}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
</DockPanel>
<Border x:Name="border"
Grid.Row="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}" />
<Grid x:Name="root"
Grid.Row="1"
SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Name="ButtonClear"
Width="Auto"
Height="Auto"
Padding="4,0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
⚠️ 设置 Panel.ZIndex="99" 为了防止代码格式化重排序,手动将 Clear 按钮置于文本框上,不然光标选中的是文本。
Panel.ZIndex="99"
hc:BorderElement.CornerRadius="4"
hc:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}"
hc:IconElement.Width="14"
Background="{TemplateBinding Background}"
Command="{x:Static hc:ControlCommands.Clear}"
Foreground="{Binding BorderBrush, ElementName=border}"
Style="{StaticResource ButtonIcon}"
Visibility="Collapsed" />
<TextBlock Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Stretch"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Style="{StaticResource TextBlockDefaultThiLight}"
Text="{Binding Path=(hc:InfoElement.Placeholder), RelativeSource={RelativeSource TemplatedParent}}"
Visibility="{TemplateBinding Text,
Converter={StaticResource String2VisibilityReConverter}}" />
<ScrollViewer x:Name="PART_ContentHost"
Grid.Row="0"
Grid.Column="0"
Margin="-2,0"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
<Button Grid.Row="0"
Grid.Column="1"
Width="Auto"
Height="Auto"
Padding="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ThicknessSplitConverter}, ConverterParameter='0,0,1,0'}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
hc:IconElement.Geometry="{StaticResource SearchGeometry}"
hc:IconElement.Width="14"
Command="{x:Static hc:ControlCommands.Search}"
Focusable="False"
Foreground="{TemplateBinding BorderBrush}"
Style="{StaticResource ButtonIcon}" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="border" Property="Opacity" Value="0.4" />
<Setter TargetName="root" Property="Opacity" Value="0.4" />
</Trigger>
<Trigger SourceName="root" Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition SourceName="root" Property="IsMouseOver" Value="true" />
<Condition Property="hc:InfoElement.ShowClearButton" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonClear" Property="Visibility" Value="Visible" />
</MultiTrigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="SearchBarPlusLeftTemplate"
TargetType="hc:SearchBar">
<Grid Height="{Binding Path=(hc:InfoElement.ContentHeight), RelativeSource={RelativeSource TemplatedParent}}"
MinHeight="{Binding Path=(hc:InfoElement.MinContentHeight), RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(hc:InfoElement.TitleWidth), RelativeSource={RelativeSource TemplatedParent}}" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<DockPanel Margin="{Binding Path=(hc:TitleElement.MarginOnTheLeft), RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="{Binding Path=(hc:TitleElement.HorizontalAlignment), RelativeSource={RelativeSource TemplatedParent}}"
VerticalAlignment="{Binding Path=(hc:TitleElement.VerticalAlignment), RelativeSource={RelativeSource TemplatedParent}}"
LastChildFill="True"
Visibility="{Binding Path=(hc:InfoElement.Title), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource String2VisibilityConverter}}">
<ContentPresenter Margin="4,0,0,0"
Content="{Binding Path=(hc:InfoElement.Symbol), RelativeSource={RelativeSource TemplatedParent}}"
DockPanel.Dock="Right"
TextElement.Foreground="{DynamicResource DangerBrush}"
Visibility="{Binding Path=(hc:InfoElement.Necessary), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource Boolean2VisibilityConverter}}" />
<TextBlock hc:TextBlockAttach.AutoTooltip="True"
Text="{Binding Path=(hc:InfoElement.Title), RelativeSource={RelativeSource TemplatedParent}}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
</DockPanel>
<Border x:Name="border"
Grid.Column="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}" />
<Grid x:Name="root"
Grid.Column="1"
SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Name="ButtonClear"
Width="Auto"
Height="Auto"
Padding="4,0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
⚠️ 设置 Panel.ZIndex="99" 为了防止代码格式化重排序,手动将 Clear 按钮置于文本框上,不然光标选中的是文本。
Panel.ZIndex="99"
hc:BorderElement.CornerRadius="4"
hc:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}"
hc:IconElement.Width="14"
Background="{TemplateBinding Background}"
Command="{x:Static hc:ControlCommands.Clear}"
Foreground="{Binding BorderBrush, ElementName=border}"
Style="{StaticResource ButtonIcon}"
Visibility="Collapsed" />
<TextBlock Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Stretch"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Style="{StaticResource TextBlockDefaultThiLight}"
Text="{Binding Path=(hc:InfoElement.Placeholder), RelativeSource={RelativeSource TemplatedParent}}"
Visibility="{TemplateBinding Text,
Converter={StaticResource String2VisibilityReConverter}}" />
<ScrollViewer x:Name="PART_ContentHost"
Grid.Row="0"
Grid.Column="0"
Margin="-2,0"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
<Button Grid.Row="0"
Grid.Column="1"
Width="Auto"
Height="Auto"
Padding="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ThicknessSplitConverter}, ConverterParameter='0,0,1,0'}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
hc:IconElement.Geometry="{StaticResource SearchGeometry}"
hc:IconElement.Width="14"
Command="{x:Static hc:ControlCommands.Search}"
Focusable="False"
Foreground="{TemplateBinding BorderBrush}"
Style="{StaticResource ButtonIcon}" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="border" Property="Opacity" Value="0.4" />
<Setter TargetName="root" Property="Opacity" Value="0.4" />
</Trigger>
<Trigger SourceName="root" Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition SourceName="root" Property="IsMouseOver" Value="true" />
<Condition Property="hc:InfoElement.ShowClearButton" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonClear" Property="Visibility" Value="Visible" />
</MultiTrigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Describe the bug
移动鼠标指针到
hc:TextBox
的边缘(靠近 Clear 按钮处),发现 ClearButton 快速闪烁。 这个问题有些控件可以通过设置UseLayoutRounding=False
来解决,但是这个方法对hc:TextBox
无效。更新
我发现官方 Demo 也会有这个问题。
Steps to reproduce the bug
Expected behavior
No response
Screenshots
No response
NuGet package version
HandyControl 3.4.0
IDE
Visual Studio 2022
Framework type
.Net 6.0
Windows version
Windows 11 (22000)
Additional context
No response