C# 使用自定义WPF控件时无法设置某些属性
所以,我有一个名为WatermarkTextbox的自定义WPF控件,它扩展了TextBox。我唯一添加到代码中的是一个字符串依赖属性,用于保存水印文本。其余的魔法在Xaml中(如下)C# 使用自定义WPF控件时无法设置某些属性,c#,wpf,xaml,custom-controls,C#,Wpf,Xaml,Custom Controls,所以,我有一个名为WatermarkTextbox的自定义WPF控件,它扩展了TextBox。我唯一添加到代码中的是一个字符串依赖属性,用于保存水印文本。其余的魔法在Xaml中(如下) 在我的应用程序中使用时: <wpfControls:WatermarkTextbox Watermark="Text that disappears."/> 大多数情况下,这是有效的。我可以设置水印文本,当我开始输入一些文本时,它就会消失。当我更改字体大小时,它会同时更改水印和我输入的文本;
在我的应用程序中使用时:
<wpfControls:WatermarkTextbox Watermark="Text that disappears."/>
大多数情况下,这是有效的。我可以设置水印文本,当我开始输入一些文本时,它就会消失。当我更改字体大小时,它会同时更改水印和我输入的文本;当我更改字体大小时,它只会更改输入的文本(这是我希望它执行的操作)。我可以更改文本框的大小。那都是肉汁
问题是当我开始尝试更改文本框的背景或边框属性时,就像这样
<wpfControls:WatermarkTextbox Watermark="Text that disappears." Background="Yellow"/>
什么也没发生。BorderBrush和BorderThickness的行为相同。现在,我知道了一些我不知道的重要概念。如果我将水印文本框的模板更改为以下内容,它将允许我在应用程序中设置所需的背景
<Style TargetType="wpfControls:WatermarkTextbox" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpfControls:WatermarkTextbox}">
<Grid>
<TextBox x:Name="baseTextBox"
Background="{TemplateBinding Background}"/>
<TextBlock Margin="5,0,0,0" x:Name="watermarkText" IsHitTestVisible="False" FontWeight="Light" FontStyle="Italic" Foreground="DarkGray"
Text="{Binding RelativeSource={RelativeSource AncestorType=wpfControls:WatermarkTextbox}, Path=Watermark}" Visibility="Hidden" Background="Transparent"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="baseTextBox" Property="Text" Value="">
<Setter TargetName="watermarkText" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我假设如果我对BorderBrush和BorderThickness做同样的操作,它们也会工作
所以,我的问题是,为什么?是什么使这些属性的行为不同于FontSize和FontWeight或高度和宽度?为什么我必须显式地将背景设置为{TemplateBinding Background},而不是FontSize?另外,我还需要为TemplateBinding设置哪些其他属性才能使其正常工作?- 它们是:;这是一个明显的特例。顺便说一句,这就是其中之一李>
- 高度和宽度不是继承的,但是您已经有了默认情况下大小与其父级相同的XAML,并且您还没有做任何事情来禁用该行为李>
TemplateBinding
操作——或者,如果它们在运行时发生更改,则需要执行relativesource绑定:
{Binding PropertyName, RelativeSource={RelativeSource TemplatedParent}}
对此没有任何“首要原则”的解释;这些都只是随意的实现细节 某些属性是自动从其父属性继承的 这就是为什么不必设置字体大小 至于“还有什么”,这完全取决于您希望能够直接在用户控件上设置什么 虽然这不是防弹的,但我的一般经验法则是“如果它是属性窗口的
笔刷选项卡中的属性,或者纯粹是为了视觉美学,它可能不会被继承”
从另一个角度来看,如果设置通常会产生奇怪的结果,那么它也可能不是继承的。示例:如果在网格
上设置了边距
属性,请想象每个子元素是否继承了相同的边距
因此,我通常会为所有非布局、视觉属性(背景、前景、边界笔刷等)添加模板绑定。或者我只是为我想直接设置到usercontrol的任何属性添加templatebindings。如果您从未打算(显式地或按样式)设置属性,则无需添加模板绑定 说得很好:“如果设置通常会产生奇怪的结果,那么它也可能不是继承的。例如:如果在网格上设置了Margin属性,想象一下如果每个子元素都继承了相同的Margin。”
{Binding PropertyName, RelativeSource={RelativeSource TemplatedParent}}