如果将文本输入到文本框触发器中,则 WPF 隐藏文本块 [英] WPF Hide TextBlock if Text is entered into TextBox Trigger

查看:21
本文介绍了如果将文本输入到文本框触发器中,则 WPF 隐藏文本块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当文本输入到我的样式中的文本框时,如何使用 XAML 触发器隐藏文本块.这是我现在得到的代码,它不起作用,没有错误,只是可能是错误的.我该怎么做?

How can I use XAML Triggers to hide a TextBlock when text is entered into the TextBox in my Style. This is the code I have got now, which doesn't work, no errors, is just probably wrong. How do I go about doing this?

<Style TargetType="TextBox">
        <Setter Property="Background" Value="#FF22252C" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Width" Value="200" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TextBox">
                    <Border CornerRadius="5" Background="#FF22252C" Margin="3" MinWidth="{TemplateBinding MinWidth}">
                        <Grid>
                            <StackPanel Margin="8">
                                <ScrollViewer x:Name="PART_ContentHost"/>
                            </StackPanel>
                            <StackPanel>
                                <TextBlock Name="PART_TempText" Text="{TemplateBinding Name}" Foreground="#FF454954" Padding="8" />
                            </StackPanel>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="Text" Value="{x:Null}">
                            <Setter TargetName="PART_TempText" Property="Foreground" Value="Red" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

推荐答案

我认为这可行,我假设您想在 TextBox

I think this would work, I assume you would like to implement a placeholder/watermark like functionality in your TextBox

<Style x:Key="CustomTextBoxStyle" TargetType="TextBox">
    <Setter Property="Background" Value="#FF22252C" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Width" Value="200" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Border CornerRadius="5" Background="#FF22252C" Margin="3" MinWidth="{TemplateBinding MinWidth}">
                    <Grid>
                        <StackPanel Margin="8">
                            <ScrollViewer x:Name="PART_ContentHost"/>
                        </StackPanel>
                        <StackPanel>
                            <TextBlock Name="PART_TempText" Text="{TemplateBinding Name}" Foreground="#FF454954"
                                       Visibility="Collapsed"
                                       Padding="8" />
                        </StackPanel>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding Text.Count, RelativeSource={RelativeSource Self}}" Value="0">
                        <Setter TargetName="PART_TempText" Property="Visibility" Value="Visible" />
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这个想法是你最初隐藏 TextBlock 并且如果 TextBoxText.Count 是 0(意味着没有输入值),显示TextBlock.

The idea is that you hide the TextBlock initially and if the TextBox's Text.Count is 0 (meaning no value is entered), you show the TextBlock.

对于你提到的关于 PasswordBox 的问题,我有一个解决方案,也许它不是最漂亮的(不是),但我还是会分享它:)

I have a solution for the issue you mentioned about PasswordBox, maybe it's not the prettiest (it's not), but I'll share it anyway :)

它不工作的原因,是因为

The reason why it doesn't work, it's because

  • It's Password.Length
  • The PasswordBox doesn't expose DependencyProperties, because it would create a security risk (https://stackoverflow.com/a/1493330/4620101)

一种可能的解决方案如下:

One possible solution is the following:

为您的项目添加一个新的附加属性:

Add a new attached property to your project:

public class PasswordBoxAttachedProperties
{
    public static readonly DependencyProperty IsPasswordEnteredProperty = DependencyProperty.RegisterAttached(
        "IsPasswordEntered", typeof (bool), typeof (PasswordBoxAttachedProperties), new PropertyMetadata(default(bool)));

    public static void SetIsPasswordEntered(DependencyObject element, bool value)
    {
        element.SetValue(IsPasswordEnteredProperty, value);
    }

    public static bool GetIsPasswordEntered(DependencyObject element)
    {
        return (bool) element.GetValue(IsPasswordEnteredProperty);
    }
}

PasswordBoxStyle 中的触发器更改为以下内容:

Change the trigger in the PasswordBox's Style to the following:

<DataTrigger Binding="{Binding (local:PasswordBoxAttachedProperties.IsPasswordEntered), RelativeSource={RelativeSource Self}}" Value="False">
    <Setter TargetName="PART_TempText" Property="Visibility" Value="Visible" />
</DataTrigger>

local 是您在应用程序中使用的命名空间映射.

local is the namespace mapping you use in your application.

添加对 System.Windows.Interactivity 的引用并创建以下 TriggerAction:

Add a reference to System.Windows.Interactivity and create the following TriggerAction:

public class NotifyPasswordChangeTrigger : TriggerAction<PasswordBox>
{
    protected override void Invoke(object parameter)
    {
        AssociatedObject.SetValue(PasswordBoxAttachedProperties.IsPasswordEnteredProperty, !string.IsNullOrEmpty(AssociatedObject.Password));
    }
}

最后,在您的 PasswordBox 中添加此触发器:

Finally, add this trigger in your PasswordBox:

<PasswordBox Name="Password">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PasswordChanged">
            <local:NotifyPasswordChangeTrigger />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</PasswordBox>

PS.:我认为您不应该使用 Name 属性作为占位符/水印.可能您应该为此创建一个新的附加属性,以便您可以像这样使用它(当然,并将 Name 中的绑定替换为您样式中的新附加属性):

PS.: I don't think you should use the Name property as the placeholder/watermark. Probably you should create a new attached property for that so you could use it like this (and replace the bindings from Name to the new attached property in your styles of course):

<PasswordBox local:TextBoxAttachedProperties.Placeholder="Please enter password...">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PasswordChanged">
            <local:NotifyPasswordChangeTrigger />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</PasswordBox>

这篇关于如果将文本输入到文本框触发器中,则 WPF 隐藏文本块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆