我有一个自定义文本框控件,我想在某个属性为true时绘制一条水平线,然后在属性为false时删除该行。该线的宽度必须是控制宽度的-2,并且距离控制底部的高度为-5。我目前正在使用带有以下OnRender
的{{3}}来完成此行为:
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
base.OnRender(drawingContext);
var rect = new Rect(AdornedElement.RenderSize);
rect.Inflate(-2, -5);
// ColoredPen is a custom class that holds a Pen object
drawingContext.DrawLine(ColoredPen.Pen, rect.BottomLeft, rect.BottomRight);
}
我遇到了一些问题,其中Adorner没有正确刷新,因此即使相关属性为true
,它也会消失。我已经尝试了几种不同的方法来确保Adorner的刷新,但它却失败了。我认为Adorner方法并不是解决我问题的正确方法。我认为如果我使用属性作为触发器的Adorner会更好。对于简单的示例,我们可以使用IsFocused
属性。这是我到目前为止的代码,但我不确定如何设置Line的X和Y属性以及如何使其工作。这个当前的代码只是崩溃应用程序(是的,我知道在这段代码中设置的行的尺寸不是我想要的,这是我试图让线条出现,我想我可以从那里调整它)。
<Style x:Key="TextBoxUnderlineTemplate" TargetType="myUi:MyTextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="myUi:MyTextBox">
<Line Name="UnderlineStuff" Stroke="Black" X1="0"
X2="{Binding RelativeSource={RelativeSource Self}, Path=Width}"
Y1="{Binding RelativeSource={RelativeSource Self}, Path=Height}"
Y2="{Binding RelativeSource={RelativeSource Self}, Path=Height}"
StrokeThickness="2" Visibility="Collapsed"/>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="UnderlineStuff" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
所以,我正在寻找一种方法来使用ControlTemplate进行此工作,或者如果还有其他建议如何使这项工作,这也是可以接受的(Adorner已经出来)。请注意,一旦这个工作,我将需要添加一个比这一行稍低的第二行,具体取决于附加属性。
答案 0 :(得分:1)
这会在IsMouseOver
上显示下划线。您可能需要改进非常简单的转换器实现,它基于字体大小:
<强> XAML:强>
<Window x:Class="WpfApplication363.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication363"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Window.Resources>
<local:MyConverter x:Key="conv1"/>
<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
<Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<Line x:Name="line1"
Y1="{TemplateBinding FontSize, Converter={StaticResource conv1}}"
X2="{Binding ElementName=border, Path=ActualWidth}"
Y2="{TemplateBinding FontSize, Converter={StaticResource conv1}}"
Stroke="Red"
Visibility="Hidden"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
<Setter Property="Visibility" TargetName="line1" Value="Visible"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TextBox Style="{DynamicResource TextBoxStyle1}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="24"
Text="Textbox with underline !"/>
</Grid>
<强>转换器:强>
public class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((double)value) + 4;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}