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

时间:2015-05-27 11:41:14

标签: c# .net 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>

行为类代码是这样的:

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)));
    }
}

我无法弄清楚为什么这不起作用。或者使用样式设置行为的属性根本不是有效的?如果这是无效的,那么另一种方式是什么。

2 个答案:

答案 0 :(得分:7)

WPF中有two types of behaviors

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

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

    <Rectangle>
        <i:Interaction.Behaviors>
            <ei:MouseDragElementBehavior />
        </i:Interaction.Behaviors>
    </Rectangle>
    

    请注意,这些行为没有任何自定义附加属性。 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...)
      }
      
      • 优点:可以在样式中定义,更易于使用
      • 缺点:繁琐的代码,实施起来有点困难
    2. 您正在将这两种行为混合在一起。选择一个并使用它!由于您希望在样式中使用它,因此您应选择实现为自定义附加属性的行为

答案 1 :(得分:3)

我开始工作了,这是我的一个小小想法。

  1. 我忘了在超链接上设置行为。
  2. 我需要获取附件的属性而不是中的属性 行为。
  3. 以下代码正常运行:

    <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>
    

    行为:

    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)));
        }
    }