DataTrigger на TextBlock не работает должным образом

Я пытаюсь реализовать текст-заполнитель для PasswordBox, следуя коду:

<PasswordBox x_Name="passwordText"/>
<TextBlock IsHitTestVisible="False" Text="Password">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Visibility" Value="Collapsed"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Password, ElementName=passwordText}" Value="">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

Вот результат:

Введите описание изображения здесь

Итак, что-то не так с кодом выше?

Кстати, я попробовал его с TextBox вместо PasswordBox, и он работал так же, как ожидалось.

3 ответа

  1. Редактировать #1

    После комментария пользователя clemens я исправил язык своего ответа.

    В property нет уведомления об измененииPassword, поэтому он не будет работать здесь. Passwordсвойство не является DP.

    Вы должны использовать простой метод обработчиков событий. Использовать PasswordBox.PasswordChangedсобытие.

  2. Как упоминалось @Anjum. Passwordсвойство in PasswordBoxне является свойством зависимости по некоторым причинам безопасности. Поэтому он не будет уведомлять о каких-либо изменениях Trigger.

    Вид обхода будет

    <Window.Resources>
        <Style TargetType="{x:Type PasswordBox}" >
            <Style.Resources>
                <VisualBrush x_Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
                    <VisualBrush.Visual>
                        <Label Content="Password" Foreground="LightGray"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Style.Resources>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Password}" Value="{x:Null}">
                    <Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
                </DataTrigger>
    
                <Trigger Property="IsKeyboardFocused" Value="True">
                    <Setter Property="Background" Value="White" />
                </Trigger>
            </Style.Triggers>
            <Setter Property="Control.Foreground" Value="#4C2C66"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
    </Window.Resources>
    
    <PasswordBox Width="200" Height="75" />
    

    Источник:

    https://stackoverflow.com/a/20342141/2819451

    https://stackoverflow.com/a/27167280/2819451

  3. Как предположил @AnjumSKhan, я сделал это с PasswordBox.PasswordChangedevent. Если у кого-то есть подобные проблемы, вот код для добавления заполнителя для PasswordBox.

    В файле xaml:

    <Window.Resources>
        <VisualBrush x_Key="PasswordPlaceHolderBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
            <VisualBrush.Visual>
                <Label Content="Нууц үг" Foreground="DarkGray"/>
            </VisualBrush.Visual>
        </VisualBrush>
    </Window.Resources>
    
    <PasswordBox PasswordChanged="passwordText_PasswordChanged" 
        Background="{StaticResource PasswordPlaceHolderBrush}"  x_Name="passwordText"/>
    

    В коде позади:

    private void passwordText_PasswordChanged(object sender, RoutedEventArgs e)
    {
        PasswordBox senderOb = (PasswordBox)sender; 
        if(senderOb.Password == "")
        {
            passwordText.Background = (VisualBrush) FindResource("PasswordPlaceHolderBrush");
        }
        else
        {
            passwordText.Background = Brushes.White; 
        }
    
    }