如果将文本输入到文本框触发器中,则 WPF 隐藏文本块 [英] WPF Hide TextBlock if Text is entered into TextBox Trigger
问题描述
当文本输入到我的样式中的文本框时,如何使用 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
并且如果 TextBox
的 Text.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
- 这是
Password.Length
PasswordBox
不会公开 DependencyProperties,因为它会产生安全风险 (https://stackoverflow.com/a/1493330/4620101)
- 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);
}
}
将 PasswordBox
的 Style
中的触发器更改为以下内容:
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屋!