在 XAML 中覆盖自定义控件样式的 属性
Override property of custom control style in XAML
我在 Stack Overflow 上从其他人那里借了一些代码。我有两个密码框。我希望第一个显示 "Password",第二个显示 "Re-enter Password"。如果唯一的区别是 TextBlock 中的文本,我不想重新编写完整的样式。如果 TargetType 必须是 PasswordBox,我如何覆盖和更改 TextBlock 的值?我正在尝试创建基于第一个样式的第二种样式,然后从那里更改它,但我不确定语法。
这个工作正常:
<Style x:Name="customPWBStyle" x:Key="customPasswordBox"
TargetType="{x:Type PasswordBox}">
<Setter Property="helper:PasswordBoxMonitor.IsMonitoring"
Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Text="Password"
Margin="4, 2, 0, 0"
Foreground="Gray"
Visibility="Collapsed"
Name="txtPrompt" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="helper:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="txtPrompt" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但我想创建另一种相同的样式,但唯一的区别必须是不得不说的 TextBlock "Re-enter password"
这是我目前得到的:
<Style x:Key="reEnterPasswordBox" BasedOn="{StaticResource customPasswordBox}" TargetType="{x:Type PasswordBox}">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="Re-enter Password"></Setter>
</Style>
</Style.Resources>
</Style>
然而它不起作用。我可以看到 TextBlock 有一个名称,即 txtPrompt,但我不确定是否可以将其用作更改 TextBlock 值的参考。
我建议在 customPasswordBox 中创建一个特殊的依赖项 属性,例如输入提示。 (如果您不能更改 customPasswordBox 代码,请创建自定义附加依赖项 属性 - 如 helper:PasswordBoxMonitor.IsMonitoring。附加 DP 非常适合参数化模板)
当你有 属性 时,通过 Setter 设置默认值,然后通过 TemplateBinding 将 TextBlock 绑定到它。
<Style x:Name="customPWBStyle" x:Key="customPasswordBox"
TargetType="{x:Type PasswordBox}">
<Setter Property="helper:PasswordBoxMonitor.IsMonitoring" Value="True"/>
<Setter Property="InputHint" Value="Password"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Text="{TemplateBinding InputHint}"
Margin="4, 2, 0, 0"
Foreground="Gray"
Visibility="Collapsed"
Name="txtPrompt" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="helper:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="txtPrompt" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
要制作另一种样式,只需更改 Setter InputHint:
<Style x:Key="reEnterPasswordBox" BasedOn="{StaticResource customPasswordBox}" TargetType="{x:Type PasswordBox}">
<Setter Property="InputHint" Value="Re-enter Password"/>
</Style>
部分模板不易修改,即使使用隐式样式也是如此
我在 Stack Overflow 上从其他人那里借了一些代码。我有两个密码框。我希望第一个显示 "Password",第二个显示 "Re-enter Password"。如果唯一的区别是 TextBlock 中的文本,我不想重新编写完整的样式。如果 TargetType 必须是 PasswordBox,我如何覆盖和更改 TextBlock 的值?我正在尝试创建基于第一个样式的第二种样式,然后从那里更改它,但我不确定语法。
这个工作正常:
<Style x:Name="customPWBStyle" x:Key="customPasswordBox"
TargetType="{x:Type PasswordBox}">
<Setter Property="helper:PasswordBoxMonitor.IsMonitoring"
Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Text="Password"
Margin="4, 2, 0, 0"
Foreground="Gray"
Visibility="Collapsed"
Name="txtPrompt" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="helper:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="txtPrompt" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但我想创建另一种相同的样式,但唯一的区别必须是不得不说的 TextBlock "Re-enter password"
这是我目前得到的:
<Style x:Key="reEnterPasswordBox" BasedOn="{StaticResource customPasswordBox}" TargetType="{x:Type PasswordBox}">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="Re-enter Password"></Setter>
</Style>
</Style.Resources>
</Style>
然而它不起作用。我可以看到 TextBlock 有一个名称,即 txtPrompt,但我不确定是否可以将其用作更改 TextBlock 值的参考。
我建议在 customPasswordBox 中创建一个特殊的依赖项 属性,例如输入提示。 (如果您不能更改 customPasswordBox 代码,请创建自定义附加依赖项 属性 - 如 helper:PasswordBoxMonitor.IsMonitoring。附加 DP 非常适合参数化模板)
当你有 属性 时,通过 Setter 设置默认值,然后通过 TemplateBinding 将 TextBlock 绑定到它。
<Style x:Name="customPWBStyle" x:Key="customPasswordBox"
TargetType="{x:Type PasswordBox}">
<Setter Property="helper:PasswordBoxMonitor.IsMonitoring" Value="True"/>
<Setter Property="InputHint" Value="Password"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Text="{TemplateBinding InputHint}"
Margin="4, 2, 0, 0"
Foreground="Gray"
Visibility="Collapsed"
Name="txtPrompt" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="helper:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="txtPrompt" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
要制作另一种样式,只需更改 Setter InputHint:
<Style x:Key="reEnterPasswordBox" BasedOn="{StaticResource customPasswordBox}" TargetType="{x:Type PasswordBox}">
<Setter Property="InputHint" Value="Re-enter Password"/>
</Style>
部分模板不易修改,即使使用隐式样式也是如此