密码框未应用样式。

10

我有以下样式定义:

<!-- Border -->
<Style x:Key="MyControlBorder" TargetType="{x:Type Border}">
    <Setter Property="BorderBrush" Value="DarkKhaki" />
    <Setter Property="Background" Value="White" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="CornerRadius" Value="10" />
</Style>

<!-- TextBox -->
<Style x:Key="MyTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Height" Value="30" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBoxBase}">
                <Border Name="TextBoxBorder" Style="{StaticResource MyControlBorder}">
                    <ScrollViewer x:Name="PART_ContentHost"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- PasswordBox -->
<Style x:Key="MyPasswordBox" TargetType="{x:Type PasswordBox}">
    <Setter Property="Height" Value="30" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Control}">
                <Border Name="Border" Style="{StaticResource MyControlBorder}">
                    <ScrollViewer x:Name="PART_ContentHost" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

以下是XAML代码:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Style="{StaticResource MyTextBox}" />
    <PasswordBox Grid.Row="1" Style="{StaticResource MyPasswordBox}" />
</Grid>

现在我得到了这个结果:垂直堆叠的一个TextBox和一个PasswordBox,其中TextBox具有卡其色、圆角边框,但PasswordBox没有任何边框。

TextBox 应用了样式,但是为什么 PasswordBox 没有应用样式呢?


你尝试过使用类似Snoop这样的工具来查找边框在运行时获取其值的位置吗?可能有些东西正在以更高的依赖属性优先级设置边框样式。 - Rachel
3个回答

3
如果您将Border包装在另一个Border中,一切都可以按预期工作(我不知道为什么)。
额外的好处是,您现在可以让PasswordBoxTextBox从相同的Style“继承”,使得事情更加简洁。
<!-- Border Style Definition -->
<Style x:Key="MyControlBorder" TargetType="Border">
    <Setter Property="BorderBrush" Value="DarkKhaki" />
    <Setter Property="Background" Value="White" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="CornerRadius" Value="10" />
</Style>

<!-- TextBox and PasswordBox Style -->
<Style x:Key="MyControlInputBox" TargetType="Control">
    <Setter Property="Height" Value="30" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Control}">
                <Border>
                    <Border Name="Border" Style="{StaticResource MyControlBorder}">
                        <ScrollViewer x:Name="PART_ContentHost" />
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- TextBox -->
<Style x:Key="MyTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource MyControlInputBox}" />

<!-- PasswordBox -->
<Style x:Key="MyPasswordBox" TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource MyControlInputBox}" />

CSS很棒,XAML不太棒:P - CRice
我还在MyControlInputBox中添加了'<Setter Property="Padding" Value="6"></Setter>',否则光标会太高。 - CRice

2

PasswordBoxControlTemplate中,Border不会使用MyControlBorder样式。

如果您像这样修改MyPasswordBox的样式...它就能够正常工作。

<Style x:Key="MyPasswordBox" TargetType="{x:Type PasswordBox}">
<Setter Property="Height" Value="30" />
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Control}">
            <Border Name="Border" BorderBrush="DarkKhaki" Background="White" BorderThickness="1" CornerRadius="10">
                <ScrollViewer x:Name="PART_ContentHost" />
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>

我知道这不是最好的解决方案...但我想不出为什么没有应用MyControlBorder。即使你去掉MyTextBox样式,它也不起作用。然后你只剩下MyControlBorderMyPasswordBox ... 它仍然不起作用。


0

PasswordBox 在这方面表现得有些奇怪,因为它明确地实现了显示此行为的功能。

默认控件模板包含一个 Border,如下所示:

<ControlTemplate TargetType="{x:Type PasswordBox}">
   <Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="True">
      <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
   </Border>
   <!-- ...other markup, triggers. -->
</ControlTemplate>

PasswordBox 的代码(取自参考源代码)执行以下操作:

因此,每当应用控件模板时,最外层的BorderStyle会被重置。正如您可以从GitHub上的代码中看到的那样,在.NET Core和>.NET中仍然是如此。这就是为什么@David Murdoch's answer中有一个多余的嵌套Border时仍然有效,因为样式应用于内部的Border

现在,你能做什么呢?你可以插入一个虚拟的Border作为解决方法,或者直接将CornerRadius设置到你自定义控件模板中的Border中。

<ControlTemplate TargetType="{x:Type Control}">
   <Border Name="Border" CornerRadius="10" Style="{StaticResource MyControlBorder}">
      <ScrollViewer x:Name="PART_ContentHost" />
   </Border>
</ControlTemplate>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接