c# - WPF 中文本框的依赖于焦点的文本更改

标签 c# .net wpf mvvm textbox

我正在使用 MVVM 模式在 WPF 中编写一个应用程序,并且会经常使用 TextBoxes。 我不想使用标签让用户知道文本框的用途,即我想要这样的东西:

<TextBlock> Name: </TextBlock>
<TextBox />

相反,我希望 TextBox 包含自己的标签。静态地,你会这样表达:

<TextBox>Name</TextBox>

如果光标显示在文本框中,即 TextBox 获得焦点,我希望描述文本消失。如果 TextBox 留空并且失去焦点,则应该再次显示描述文本。它类似于 StackOverflow 或 Firefox 的搜索文本框。 (如果您不确定我的意思,请告诉我)。

一个 TextBox 的标签可能会在运行时改变,这取决于例如ComboBox 的选定元素或我的 ViewModel 中的值。 (就像在 Firefox 的搜索文本框中,如果您从搜索引擎的菜单中选择 google,文本框的标签将更改为“Google”,如果您选择“Yahoo”,则其设置为“Yahoo”)。因此我希望能够绑定(bind)标签的内容。

考虑到我可能已经在 Text 上绑定(bind)了一个 Binding - TextBox 的属性。

如何实现这样的行为并使其可重用用于我的任何 TextBox?代码是受欢迎的,但不是必需的;描述要做什么就足够了。

提前谢谢你。

最佳答案

我认为这是您正在寻找的样式,它是纯 XAML。

<Style x:Key="WatermarkTextBox" TargetType="{x:Type TextBox}">
     <Setter Property="Template">
          <Setter.Value>
               <ControlTemplate TargetType="{x:Type TextBox}">
                    <Grid>
                         <Border x:Name="BorderBase" Background="White" BorderThickness="1.4,1.4,1,1" BorderBrush="Silver"> 
                             <Label x:Name="TextPrompt" 
                                Content="{Binding RelativeSource={RelativeSource  Mode=TemplatedParent}, Path=Tag}" 
                                Background="{TemplateBinding Background}" Visibility="Collapsed" 
                                Focusable="False" Foreground="Silver"/>
                         </Border>
                         <ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="Black"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                         <MultiTrigger>
                              <MultiTrigger.Conditions>
                                   <Condition Property="IsFocused" Value="False"/>
                                   <Condition Property="Text" Value=""/>
                              </MultiTrigger.Conditions>
                              <Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"/>
                         </MultiTrigger>
                         <Trigger Property="IsFocused" Value="True">
                              <Setter Property="BorderBrush" TargetName="BorderBase" Value="Black"/>
                         </Trigger>
                         <Trigger Property="IsEnabled" Value="False">
                              <Setter Property="Foreground" Value="DimGray" />
                         </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
           </Setter.Value>
      </Setter>
 </Style>

用法是:

<TextBox Style="{StaticResource WatermarkTextBox}" Tag="Full Name"/>

其中 Tag 是您要显示的帮助消息。

您可以清理此样式供您自己使用,但最重要的部分是控制隐藏/显示帮助文本的控件。

同样值得注意的是,已经有一个 DependencyObject 可用于存储帮助文本,因此您无需使用此方法创建自己的对象。

FrameworkElement.Tag 可用于保存有关此元素的任意信息。这就是我们设置 Tag 属性的原因:

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.tag.aspx

关于c# - WPF 中文本框的依赖于焦点的文本更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3028494/

相关文章:

c# - 当您创建一个参数包含 2 个对象但仅更改 1 个的方法时,什么是好的做法

c# - 两者参数赋值的区别

c# - 检查 Int32.TryParse 的更简单方法

.net - 声明 ClientBase 期间设备崩溃

c# - 在 C# 中使用结构的单例

c# - 为什么我得到 "The given path' 格式不受支持”错误

wpf - 使用 WPF 的超快速位图渲染,最佳解决方案?

c# - 是我错了还是 Roslyn REPL 保护过度了?

c# - 我有 WPF 窗口,我想在纸张尺寸 **4 英寸乘 6 英寸**上打印

c# - 将 WPF Datagrid 列设置为 Combobox itemssource