触发器与目标名称

12
我在WPF中有几个文本框和一组单选按钮。 我想使用触发器,在任何一个文本框获得焦点时将名字为"IsChecked"的一个单选按钮的"IsChecked"属性设置为true。 我查看了一些示例,但没有找到我要找的内容。 请记住,我们正在使用MVVM模式,没有代码后台。 我尝试了以下代码,并出现了编译错误: 目标名称属性无法在样式Setter上设置。
<UserControl.Resources>
            <Style x:Name="myTest" TargetType="TextBox">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="RadioButton.IsChecked" Value="True"  TargetName="myRadioButton"></Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </UserControl.Resources>

我阅读了其他帖子,使用DataTrigger解决了问题。

 <Style x:Name="myTest2" TargetType="RadioButton" >
     <Style.Triggers>
        <DataTrigger Binding="{Binding IsFocused, ElementName=myTextBox}" Value="True">
           <Setter Property="IsChecked"  Value="True" ></Setter>
        </DataTrigger>      
    </Style.Triggers>
 </Style>

1
如果您能展示至少XAML代码,那将会很有帮助 ;) - Florian Gl
你可以将此属性设置为应用Setter集合(此Setter所属的集合)范围内的任何元素的名称。通常,这是一个在包含此Setter的模板中的命名元素。TargetName主要用于控件模板中,而不仅仅是像你尝试使用它的样式中。 - Tejas Sharma
5
在WPF触发器、样式和模板的交叉口,是否有其他人也经常遇到这种问题?无法在样式setter中使用TargetName。除非在样式中,触发器集合只能有EventTriggers。糟糕,那个控件只能在控件模板中使用,不能在数据模板中使用... - user1454265
4个回答

2
为每个RadioButton编写样式,提供相应的TextBox作为触发元素。以下是三个TextBox和三个RadioButtons的示例。
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <TextBox x:Name="txtBox0" Grid.Row="0"/>
    <TextBox x:Name="txtBox1" Grid.Row="1"/>
    <TextBox x:Name="txtBox2" Grid.Row="2"/>

    <StackPanel Grid.Row="3" Orientation="Horizontal">
        <RadioButton GroupName="grp1" Content="txt1">
            <RadioButton.Style>
                <Style TargetType="RadioButton">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsFocused, ElementName=txtBox0}" Value="True">
                            <Setter Property="IsChecked" Value="True"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </RadioButton.Style>
        </RadioButton>
        <RadioButton GroupName="grp1" Content="txt2">
            <RadioButton.Style>
                <Style TargetType="RadioButton">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsFocused, ElementName=txtBox1}" Value="True">
                            <Setter Property="IsChecked" Value="True"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </RadioButton.Style>
        </RadioButton>
        <RadioButton GroupName="grp1" Content="txt3">
            <RadioButton.Style>
                <Style TargetType="RadioButton">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsFocused, ElementName=txtBox2}" Value="True">
                            <Setter Property="IsChecked" Value="True"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </RadioButton.Style>
        </RadioButton>
    </StackPanel>
</Grid>

Derp,一个简单的解决方案。 - Billy Jake O'Connor

1
创建一个ControlTemplate并将您的触发器添加到ControlTemplate.Triggers中。
<ControlTemplate.Triggers>
    <Trigger Property="HasText" Value="True">
        <Setter Property="Visibility" TargetName="LabelText" Value="Hidden" />
     </Trigger>
</ControlTemplate.Triggers>

这段代码应该添加在哪里? - javirs
这应该放在XAML的资源部分。 - Pale Ale

1

来自 MSDN:

您可以将此属性设置为应用此 setter 的范围内任何元素的名称(此 setter 是该集合的一部分)。通常,这是一个命名元素,位于包含此 setter 的模板中。

TargetName 主要在控件模板中使用,而不仅仅是在您试图使用它的样式中。您可以将 RadioButtonIsChecked DP 绑定到 TextBoxIsMouseOver DP。


0

我觉得你在寻找 GotFocus 事件。

在 XAML 中:

<TextBox x:Name="textBox1" GotFocus="tb_GotFocus"/>
<TextBox x:Name="textBox2" GotFocus="tb_GotFocus"/>
<TextBox x:Name="textBox3" GotFocus="tb_GotFocus"/>
<RadioButton x:Name="myRadioButton"/>

然后在你的 C# 中,你的事件处理程序可能看起来像这样

private void tb_GotFocus(object sender, RoutedEventArgs e)
{
    myRadioButton.IsChecked = true;
}

如果任何一个文本框获得焦点,它将检查名为myRadioButton的单选按钮。

2
嗯,我忘了告诉你我们正在使用MVVM和无代码后端。 - AustinTX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接