如何编写数据触发器以根据第二个依赖项属性的更改来更改依赖项属性的值?

时间:2011-10-18 16:26:13

标签: wpf xaml user-controls triggers

我想更改由第二个依赖项属性(ViewType)的更改更改触发的UserControl中的依赖项属性(Mode)的状态。

我尝试按如下方式定义DataTrigger,但由于某种原因它不起作用:

<UserControl.Resources>
    <Style TargetType="{x:Type UserControls:MyUserControl}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ViewType}" Value="ViewType2">
                <Setter Property="Mode" Value="Logon"/>
            </DataTrigger>
      </Style.Triggers>
    </Style>
</UserControl.Resources>

为了验证我的绑定是否正常工作,我在同一个用户控件中编写了以下测试XAML:

    <Style x:Key="butstyle">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ViewType}" Value="ViewType2">
                <Setter Property="Control.Foreground" Value="White"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

当我将这个样式分配给一个按钮时,我看到前景颜色在正确的时间变为白色,这证明了我对ViewType的绑定正在起作用。

我似乎需要在usercontrol.resources下使用样式(如上面第一段代码中所示),但是从不设置“Mode”属性。

这是正确的方法吗?如果可能的话,我想尝试将其保留在XAML中,但是当我们不直接与视觉元素相关时触发器应该如何工作我感到不舒服。

如果相关,则在父UserControl中定义“ViewType”绑定属性,并在MyUserControl上定义“Mode”属性。

更新

我使用转换器来查明我的触发器正在被调用,但是由于某种原因,我的setter没有参与。这是我想要设置的DP的代码。调用set()和OnModeChanged()的断点。我的依赖属性有什么问题吗?

    public enum ModeStates { Logon, NextState }

    public ModeStates Mode
    {
        get { return (ModeStates)GetValue(ModeProperty); }
        set { SetValue(ModeProperty, value); }
    }

    protected static readonly DependencyProperty ModeProperty = DependencyProperty.Register(
            "Mode", typeof(ModeStates), typeof(MyUserControl),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnModeChanged))
            );


    private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {

            // .......

    }

更新

我能够使用DependencyPropertyDescriptor.AddValueChanged()以非常干净的方式解决我的问题。

2 个答案:

答案 0 :(得分:4)

如果在UserControl上定义了相关的依赖项属性,则需要设置它的样式属性,而不是在资源中添加默认样式。

在XAML中设置内联样式

<UserControl.Style>
    <Style TargetType="{x:Type UserControls:MyUserControl}">
      <!-- Triggers -- >
    </Style>
</UserControl.Style>

答案 1 :(得分:2)

除了Adam's answer之外,您是否在Mode标记的任何位置设置了<UserControl>属性?如果这样做,它将覆盖触发的值。

此外,有时我遇到了触发值未设置的问题,除非在样式中也定义了默认值。

例如,有时这不起作用

<UserControl.Style>
    <Style TargetType="{x:Type UserControls:MyUserControl}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ViewType}" Value="ViewType2">
                <Setter Property="Mode" Value="Logon"/>
            </DataTrigger>
      </Style.Triggers>
    </Style>
</UserControl.Style>

虽然这样做

<UserControl.Style>
    <Style TargetType="{x:Type UserControls:MyUserControl}">
        <Setter Property="Mode" Value="{x:Null}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ViewType}" Value="ViewType2">
                <Setter Property="Mode" Value="Logon"/>
            </DataTrigger>
      </Style.Triggers>
    </Style>
</UserControl.Style>