【问题标题】:WPF: Can I define/set an attached property through a style?WPF:我可以通过样式定义/设置附加属性吗?
【发布时间】:2011-02-02 14:54:50
【问题描述】:

有没有办法通过样式设置附加属性?

我有例如设置交互内容的按钮(来自 System.Windows.Interactivity)

<Button>
  <i:Interaction.Triggers>
    ...
  </i:Interaction.Triggers>
</Button>

现在我想创建一个设置 Interaction.Triggers 属性的样式,从而通过必须在每个 Button 实例上指定该属性来替换冗余。这在 WPF 中可行吗?

<Style Target={x:Type Button}>
  <!-- ??? -->
  <Setter PropertyName="i.Interaction.Triggers">
  ...

不知怎的,我不知道怎么做,但我在网络上看到了其他示例,其中附加属性似乎可以从样式中访问...

更新

所以基本上这是一个 Interaction.Triggers 没有办法“设置”某些东西的问题。我应该如何重用一组交互定义?

【问题讨论】:

标签: .net wpf silverlight


【解决方案1】:

这是只读集合属性的一个已知问题(与 InputBindings 集合相同)。为了解决这个问题,我创建了一个附加属性:

public static StyleTriggerCollection GetTriggers(DependencyObject obj) {
    return (StyleTriggerCollection)obj.GetValue(TriggersProperty);
}

public static void SetTriggers(DependencyObject obj, StyleTriggerCollection value) {
    obj.SetValue(TriggersProperty, value);
}

public static readonly DependencyProperty TriggersProperty =
    DependencyProperty.RegisterAttached("Triggers", typeof(StyleTriggerCollection), typeof(ControlExtensions), new UIPropertyMetadata(null, OnTriggersChanged));

static void OnTriggersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var triggers = (StyleTriggerCollection) e.NewValue;

    if (triggers != null) {
        var existingTriggers = Interaction.GetTriggers(d);

        foreach (var trigger in triggers) {
            existingTriggers.Add((TriggerBase)trigger.Clone());
        }
    }
}

该属性使用自定义 StyleTriggerCollection,因为标准触发器集合没有公共构造函数:

public class StyleTriggerCollection : Collection<TriggerBase>
{
}

在样式设置器中,您可以像这样使用它:

<Setter Property="my:ControlExtensions.Triggers">
    <Setter.Value>
        <my:StyleTriggerCollection>
            <!-- Put your triggers here -->
        </my:StyleTriggerCollection>
    </Setter.Value>
</Setter>

【讨论】:

  • 这看起来很有希望,我一回到代码上就会看看!
  • 这似乎可行,但我对在触发器中使用 DataContext 感到困惑。我似乎无法让 RelativeSource AncestorType 等工作......
  • 您需要了解相对来源的工作原理。它适用于视觉树中的元素。在这种情况下,触发器不在可视树中 - 触发器集合只是可视树中元素的属性。在这种情况下数据上下文继承起作用的原因是触发器继承了 Freezable。你可以在这里阅读:drwpf.com/blog/category/freezables
  • 我走的是一条稍微不同的路线,因为我认为我做了所有必要的步骤来支持 Freezable 的功能,但它不起作用。无论如何,更多的努力应该可以证明这很好,所以这对我来说是一个答案:)
  • 这对我 Pavlo 来说非常有效。一个恼人的问题的优雅解决方案。 +1
猜你喜欢
  • 2018-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-13
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
相关资源
最近更新 更多