在WPF样式中使用自定义属性

时间:2016-06-21 15:43:08

标签: c# .net wpf xaml

我有这个文本框:

<TextBox/>

我想在其中添加一个水印,Enter your message here...

由于它不支持开箱即用,这成功地解决了这个问题:

<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <Style.Resources>
        <VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
            <VisualBrush.Visual>
                <Label Content="Enter your message here..." Foreground="LightGray" Padding="10 0 0 0" />
            </VisualBrush.Visual>
        </VisualBrush>
    </Style.Resources>
    <Style.Triggers>
        <Trigger Property="Text" Value="{x:Static sys:String.Empty}">
            <Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
        </Trigger>
        <Trigger Property="Text" Value="{x:Null}">
            <Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
        </Trigger>
        <Trigger Property="IsKeyboardFocused" Value="True">
            <Setter Property="Background" Value="White" />
        </Trigger>
    </Style.Triggers>
</Style>

但是有没有办法使用TextBox XAML属性扩展WatermarkText,如下所示并让我的风格选择并使用它,或者是否有其他方法可以这样做(C#等)?

<TextBox WatermarkText="Enter your message here..."/>

2 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是使用可以在样式中绑定的附加依赖项属性。请记住,绑定附加的依赖项属性是

Text={Binding (AttachedPropertyName)}

()制作技巧。

看看Mahapps。这是一个很好的设计框架,并提供了一个TextBoxHelper类来完成这一切。它是开源的,因此您可以看到它是如何使用附加属性实现的。

答案 1 :(得分:0)

最简单的方法就是将标签放在与文本框相同的位置,而不是.xaml中的命中测试可见性:

<TextBox Name="Username" Grid.Row="2" Height="40" FontFamily="Segoe UI" FontSize="20" VerticalContentAlignment="Center" TextChanged="Username_TextChanged"/>
<Label Name="UsernameLabel" Content="Username" Grid.Row="2" FontFamily="Segoe UI" FontSize="20" Foreground="LightGray" Padding="5" IsHitTestVisible="False" />

.cs

private void Hostname_TextChanged(object sender, TextChangedEventArgs e)
{
    UpdateLabel(Hostname, HostnameLabel);
}

private void UpdateLabel(TextBox textBox, Label label)
{
    label.Visibility = String.IsNullOrWhiteSpace(textBox.Text) ? Visibility.Visible : Visibility.Hidden;
}

这也适用于密封的密码框so you cannot inherit them anyways if you tried to extend sealed controls