如何使用数据触发器设置WPF行为属性

Ran*_*eep 6 .net c# wpf xaml

我试图通过以下方式使用样式设置WPF行为属性:

<StackPanel>
    <CheckBox Name="IsFemaleChkBox" Content="Is Female ?" />
    <TextBlock>
        <Hyperlink> <!--setting property directly like this:  local:MyHyperLinkBehavior.Salutation="Mr." isn't working either-->
            <TextBlock Text="My Hyperlink"/>
            <Hyperlink.Style>
                <Style TargetType="Hyperlink">
                    <Setter Property="local:MyHyperLinkBehavior.Salutation" Value="Mr." />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsChecked, ElementName=IsFemaleChkBox}" Value="True">
                            <Setter Property="local:MyHyperLinkBehavior.Salutation" Value="Miss" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Hyperlink.Style>
        </Hyperlink>
    </TextBlock>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

行为类代码是这样的:

class MyHyperLinkBehavior : Behavior<Hyperlink>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Click += AssociatedObject_Click;
    }

    public static bool GetIsFemale(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFemaleProperty);
    }

    public static void SetIsFemale(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFemaleProperty, value);
    }

    // Using a DependencyProperty as the backing store for IsFemale.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsFemaleProperty =
        DependencyProperty.RegisterAttached("IsFemale", typeof(bool), typeof(MyHyperLinkBehavior), new PropertyMetadata(false));


    public static string GetSalutation(DependencyObject obj)
    {
        return (string)obj.GetValue(SalutationProperty);
    }

    public static void SetSalutation(DependencyObject obj, string value)
    {
        obj.SetValue(SalutationProperty, value);
    }

    // Using a DependencyProperty as the backing store for Salutation.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SalutationProperty =
        DependencyProperty.RegisterAttached("Salutation", typeof(string), typeof(MyHyperLinkBehavior), new PropertyMetadata(default(string)));

    void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        MessageBox.Show(Convert.ToString(GetValue(SalutationProperty)));
    }
}
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么这不起作用.或者使用样式设置行为的属性根本无效?如果这是无效的,那么反过来是什么.

Lie*_*ero 9

WPF中有两种类型的行为:

  1. System.Windows.Interactivity行为,也称为混合行为

    这些行为是继承自的类System.Windows.Interactivity.Behavior,您可以通过将其添加到Behaviors集合中来添加使用它们,例如:

    <Rectangle>
        <i:Interaction.Behaviors>
            <ei:MouseDragElementBehavior />
        </i:Interaction.Behaviors>
    </Rectangle>
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,这些行为没有任何自定义附加属性.自动调用OnAttached和OnDetached方法.

    • 优点:易于实施
    • 缺点:不适用于样式(但是,它适用于ControlTemplates和DataTemplates)
  1. 作为自定义附加属性实现的行为

    在这些行为中,自定义附加属性的PropertyChangedCallback中定义了逻辑.

    public static readonly DependencyProperty SalutationProperty =
       DependencyProperty.RegisterAttached("Salutation",
            typeof(string),
            typeof(MyHyperLinkBehavior),
            new PropertyMetadata(OnSalutationPropertyChanged));
    
    
    private static void OnSalutationPropertyChanged(object sender,
                                             DependencyPropertyChangedEventArgs e)
    {
         //attach to event handlers (Click, Loaded, etc...)
    }
    
    Run Code Online (Sandbox Code Playgroud)
    • 优点:可以定义样式,更易于使用
    • 缺点:很好的代码,实现起来有点困难

您将这两种行为混合在一起.选择一个并使用它!由于您希望在样式中使用它,因此您应选择实现为自定义附加属性的行为


Ran*_*eep 4

我让它工作了,这是我的一个小失误。

  1. 我忘记设置超链接的行为。
  2. 我需要获取 AttachedObject 的属性而不是
    行为的属性。

以下代码工作正常:

<StackPanel>
    <CheckBox Name="IsFemaleChkBox" Content="Is Female ?" />
    <TextBlock>
        <Hyperlink>
            <TextBlock Text="My Hyperlink"/>
            <i:Interaction.Behaviors> <!--Missed setting behavior-->
                <local:MyHyperLinkBehavior />
            </i:Interaction.Behaviors>
            <Hyperlink.Style>
                <Style TargetType="Hyperlink">
                    <Setter Property="local:MyHyperLinkBehavior.Salutation" Value="Mr." />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsChecked, ElementName=IsFemaleChkBox}" Value="True">
                            <Setter Property="local:MyHyperLinkBehavior.Salutation" Value="Miss" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Hyperlink.Style>
        </Hyperlink>
    </TextBlock>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

以及行为:

class MyHyperLinkBehavior : Behavior<Hyperlink>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Click += AssociatedObject_Click;
    }

    public static bool GetIsFemale(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFemaleProperty);
    }

    public static void SetIsFemale(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFemaleProperty, value);
    }

    // Using a DependencyProperty as the backing store for IsFemale.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsFemaleProperty =
        DependencyProperty.RegisterAttached("IsFemale", typeof(bool), typeof(MyHyperLinkBehavior), new PropertyMetadata(false));


    public static string GetSalutation(DependencyObject obj)
    {
        return (string)obj.GetValue(SalutationProperty);
    }

    public static void SetSalutation(DependencyObject obj, string value)
    {
        obj.SetValue(SalutationProperty, value);
    }

    // Using a DependencyProperty as the backing store for Salutation.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SalutationProperty =
        DependencyProperty.RegisterAttached("Salutation", typeof(string), typeof(MyHyperLinkBehavior), new PropertyMetadata(default(string)));

    void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        // Changing "GetValue(SalutationProperty)" to "this.AssociatedObject.GetValue(SalutationProperty)" works
        MessageBox.Show(Convert.ToString(this.AssociatedObject.GetValue(SalutationProperty)));
    }
}
Run Code Online (Sandbox Code Playgroud)