好的,乍一看这可能看起来很奇怪,但我相信这是正确的方法。我从 a 派生TextBox
并添加ContentPresenter
到那里以托管任何内容和Content
设置该内容的属性。
因此,创建名为 TextBoxContainer 的 WPF 自定义控件(它是 Visual Studio 模板)。向其中添加以下属性:
#region Content (DependencyProperty)
/// <summary>
/// Gets or sets Content property
/// </summary>
public object Content
{
get { return (object)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(object), typeof(TextBoxContainer),
new PropertyMetadata(null));
#endregion
将 Assets/generic.xaml 文件中的样式替换为以下内容:
<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 TargetType="{x:Type local:TextBoxContainer}">
<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"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TextBoxContainer}">
<Grid>
<Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Microsoft_Windows_Themes:ListBoxChrome>
<ContentPresenter Content="{TemplateBinding Content}"/>
</Grid>
<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>
并像下面这样使用它:
<local:TextBoxContainer TextChanged="TextBoxGrid_TextChanged" >
<local:TextBoxContainer.Content>
<Grid>
<!-- Any markup here -->
</Grid>
</local:TextBoxContainer.Content>
</local:TextBoxContainer>
请注意,在任何时候它都有包含所有输入文本的文本。您应该注意的唯一一件事是某些元素会阻止某些事件冒泡。例如TextBox
停止KeyDown
事件冒泡。因此,如果您放置TextBox
在TextBoxContainer
其中并且用户将单击它并开始在那里输入文本 - TextBoxContainer 将不会接收该文本,尽管它会触发TextChanged
事件。