Wpf 带有部分固定内容的自定义文本框
我需要在WPF中创建一个自定义文本框,该文本框将包含一些数字和字符串“%Per year”,如“55%”。用户应该只能更改文本框中的数字,我想保持字符串“%Per year”不可编辑。请帮助我。在WPF中,您可以修改控件的模板以完全更改外观,同时保留功能。在本例中,您可以通过在控件边框内添加一些额外文本来修改Wpf 带有部分固定内容的自定义文本框,wpf,xaml,Wpf,Xaml,我需要在WPF中创建一个自定义文本框,该文本框将包含一些数字和字符串“%Per year”,如“55%”。用户应该只能更改文本框中的数字,我想保持字符串“%Per year”不可编辑。请帮助我。在WPF中,您可以修改控件的模板以完全更改外观,同时保留功能。在本例中,您可以通过在控件边框内添加一些额外文本来修改文本框的控件模板 在VisualStudio中,将文本框添加到XAML中。然后在文档大纲中右键单击文本框,然后选择编辑模板=>编辑副本…。然后将文本框的样式添加到XAML中,包括默认文本框使
文本框的控件模板
在VisualStudio中,将文本框添加到XAML中。然后在文档大纲中右键单击文本框
,然后选择编辑模板=>编辑副本…。然后将文本框
的样式
添加到XAML中,包括默认文本框
使用的控制模板的副本。然后可以根据需要修改模板
文本框的主要部分是ListBoxChrome
边框内的ScrollViewer
。要获得所需的结果,您可以将ScrollViewer
包装在一个网格中,该网格有两列,然后在第二列中放置一个TextBlock
,文本为“%perior”。您可能还希望右对齐文本框中的文本
,默认情况下,您可以通过在文本框
的样式
中将水平内容对齐
设置为右对齐
下面是一个完整的XAML示例,我在其中添加了一些注释,以显示我在何处进行了编辑:
<Window
x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
<GradientStop Color="#ABADB3" Offset="0.05"/>
<GradientStop Color="#E2E3EA" Offset="0.07"/>
<GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style x:Key="PerAnnumTextBoxStyle" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<!-- New setter -->
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
<!-- ScrollViewer wrapped in a Grid -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Grid.Column="1" Margin="0,1"> % Per Annum</TextBlock>
</Grid>
</Themes:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</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>
<StackPanel>
<TextBox Text="50" Style="{StaticResource PerAnnumTextBoxStyle}" Width="100" HorizontalAlignment="Left"/>
</StackPanel>
</Window>
%每年
在WPF中,您可以修改控件的模板以完全更改外观,同时保留功能。在本例中,您可以通过在控件边框内添加一些额外文本来修改文本框的控件模板
在VisualStudio中,将文本框添加到XAML中。然后在文档大纲中右键单击文本框
,然后选择编辑模板=>编辑副本…。然后将文本框
的样式
添加到XAML中,包括默认文本框
使用的控制模板的副本。然后可以根据需要修改模板
文本框的主要部分是ListBoxChrome
边框内的ScrollViewer
。要获得所需的结果,您可以将ScrollViewer
包装在一个网格中,该网格有两列,然后在第二列中放置一个TextBlock
,文本为“%perior”。您可能还希望右对齐文本框中的文本
,默认情况下,您可以通过在文本框
的样式
中将水平内容对齐
设置为右对齐
下面是一个完整的XAML示例,我在其中添加了一些注释,以显示我在何处进行了编辑:
<Window
x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
<GradientStop Color="#ABADB3" Offset="0.05"/>
<GradientStop Color="#E2E3EA" Offset="0.07"/>
<GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style x:Key="PerAnnumTextBoxStyle" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<!-- New setter -->
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
<!-- ScrollViewer wrapped in a Grid -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Grid.Column="1" Margin="0,1"> % Per Annum</TextBlock>
</Grid>
</Themes:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</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>
<StackPanel>
<TextBox Text="50" Style="{StaticResource PerAnnumTextBoxStyle}" Width="100" HorizontalAlignment="Left"/>
</StackPanel>
</Window>
%每年
在我看来,最简单也是更好的方法是将文本框放在堆栈面板中
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=MyTextProperty}"/>
<Label Content="55% Per Annum" />
</StackPanel>
在我看来,最简单也是更好的方法是将文本框放在堆栈面板中
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=MyTextProperty}"/>
<Label Content="55% Per Annum" />
</StackPanel>
这听起来像是一个非常非标准的UI,因此(相对)昂贵。没有办法让该单元以更平台标准的方式生活在文本框之外吗?这听起来像是一个非常非标准的UI,因此(相对)昂贵。该装置是否无法以更为平台标准的方式生活在文本框之外?