【问题标题】:How to properly apply a DataTrigger binding inside a WPF style for a different component type?如何在 WPF 样式中为不同的组件类型正确应用 DataTrigger 绑定?
【发布时间】:2015-12-01 15:19:53
【问题描述】:

在 WPF 方面,我还是有点不适应。我目前正在处理一个上面有几个文本框的 WPF 表单。这些 TextBox 中的每一个都与位于相同 x,y 坐标中的 TextBlock 配对,充当 GhostText。一旦您在 TextBox 内单击,GhostText 就会消失。

以下是最初如何在表单的 XAML 中设置绑定的示例(所有文本框都重复了相同的代码,因此使用样式背后的原因):

<TextBox Grid.Column="0" Width="40" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" x:Name= "RecordMinutesTextBox" Padding="12,5,5,0" Text ="{Binding RecordMinute}"  Margin="0,25,5,1" PreviewTextInput="CheckNumberValidation" Background="{Binding ElementName=FireWashingtonResponseTimeReport,Path=DataContext.RequiredFieldColor}"/>
<TextBlock Grid.Column="0" Width="40"  IsHitTestVisible="False" Text="MIN" VerticalAlignment="Center" HorizontalAlignment="Left" Foreground="DarkGray" Margin="8,25,0,1"                               >
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Visibility" Value="Collapsed"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Text, ElementName=RecordMinutesTextBox}" Value="">
                    <Setter Property="Visibility" Value="Visible"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

*注意多个文本框之一的名称,“RecordMinutesTextBox”,用作 DataTrigger 绑定的 ElementName。

这是我的 WPF 样式模板中的代码:

<Style x:Key="MinuteAndSecondsGhostText" TargetType="TextBlock">
    <Setter Property="Width" Value="40"/>
    <Setter Property="IsHitTestVisible" Value="False"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Setter Property="Foreground" Value="DarkGray"/>
    <Setter Property="Visibility" Value="Collapsed"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Text, ElementName=??WhatDoIPutHere??}" Value="">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
    </Style.Triggers>
</Style>enter code here

所以我的问题真的归结为这个。我应该在 DataTrigger 绑定中使用什么作为此样式的 ElementName?考虑到我的表单上有多个不同名称的文本框。提前致谢。

【问题讨论】:

  • @ThomasBomans 我感谢编辑建议。谢谢。

标签: c# wpf xaml


【解决方案1】:

我给你一个想法……你可以根据它改变你的代码。

在我的以下示例中,您会看到TextBlock 显示TextBox 的IsFocused 属性的状态。因此,您可以将这对元素放在像StackPanel 这样的父级中,并通过RelativeSource 而不是ElementName 访问另一个子级中一个子级的属性...

只需将此代码放在您的窗口中并将focus 放在TextBox 中,您在TextBlock 中看到了什么?

<StackPanel Orientation="Horizontal" Background="White"  Margin="20">

 <TextBox Text="" Name="TextBox" Background="DarkSalmon" Width="100" Height="30"/>

 <TextBlock Text="{Binding Path=Children[0].IsFocused,
                           RelativeSource={RelativeSource Mode=FindAncestor,
                                                          AncestorType={x:Type StackPanel}}}"
               Margin="20,0"/>
</StackPanel>

编辑:

根据我的上述想法,您可以使用RelativeSource 而不是ElementName 来解决您的问题,如下例所示:

<Style x:Key="MinuteAndSecondsGhostText" TargetType="TextBlock">
    <Setter Property="Width" Value="40"/>
    <Setter Property="IsHitTestVisible" Value="False"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Setter Property="Foreground" Value="DarkGray"/>
    <Setter Property="Visibility" Value="Collapsed"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=Children[0].Text,
                               RelativeSource={RelativeSource Mode=FindAncestor,
                                                              AncestorType={x:Type StackPanel}}}" Value="">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

在你的Window 正文中:

<StackPanel x:Name="Pair1" Orientation="Horizontal" Background="White"  Margin="20">
    <!--TextBox should be first child of StackPanel-->
    <TextBox Text="" Name="TextBox1" Background="DarkSalmon" Width="100" Height="30"/>
    <TextBlock Text="Sample Text" Style="{StaticResource MinuteAndSecondsGhostText}" Margin="20,0"/>
</StackPanel>

<StackPanel x:Name="Pair2" Orientation="Horizontal" Background="White"  Margin="20">
    <!--TextBox should be first child of StackPanel-->
    <TextBox Text="" Name="TextBox2" Background="DarkSalmon" Width="100" Height="30"/>
    <TextBlock Text="Sample Text" Style="{StaticResource MinuteAndSecondsGhostText}" Margin="20,0"/>
</StackPanel>

【讨论】:

  • 感谢您的想法。我现在正在尝试。如果它满足我的需要,我会告诉你的。
  • 不幸的是,这并不能解决我的问题。以这种方式使用 TextBlock 中的 text 属性会删除我的 Ghost Text 功能。我需要弄清楚的代码与 TextBlock 的 DataTrigger 有关。
  • 您写道:一旦您在 TextBox 内单击,GhostText 就会消失。 首先请告诉我这是您想要的吗? 如果这是您想要的然后想要使用RelativeSource 而不是ElementName 类似我的代码。我将第一个孩子(TextBox)的IsFocused 属性绑定到TextBlock 的Text 属性。您可以通过BooleanToVisibilityConverter 将IsFocused 绑定到Visibility 属性。您需要更多帮助来实现这一点吗?
  • 我的代码在没有样式的情况下按预期“工作”。通过按照您的建议实现 text 属性会破坏我已经拥有和想要的功能。我的文本块的文本属性用于显示重影文本。如前所述,我正在尝试重写文本块的 DataTrigger;允许使用具有应用样式的任何文本框组件。因此,很遗憾,您的解决方案不适用于我的情况。
  • 这个想法是使用RelativeSource和Path=Children[0]!无论如何,我将新示例附加到我的答案中以直接为您提供帮助。
猜你喜欢
  • 2013-07-10
  • 2013-10-19
  • 2015-06-29
  • 2019-04-29
  • 1970-01-01
  • 2015-08-03
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多