12

我正在尝试从 XAML 填充依赖项属性。依赖属性是IEnumerable<KeyAction>其中 KeyAction 是复杂类型的地方。

<loc:MyType.KeyActions>
    <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
    <loc:KeyAction Action="Hide" Key="Escape" />
</loc:MyType.KeyActions>

现在,这会导致KeyAction属性“声明两次”,因为 XAML 将每个项目解释为该属性的候选对象,而不是列表中的项目。

为此,它需要看起来像:

<loc:CompletionPopupView.KeyActions>
    <sys:List`KeyAction>
        <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
        <loc:KeyAction Action="Hide" Key="Escape" />
    </sys:List`KeyAction>
</loc:CompletionPopupView.KeyActions>

而且我需要添加名称空间,通用语法可能更糟糕,即使可行。有什么方法可以使第一个示例起作用吗?

4

1 回答 1

24

有两种不同的方法可以使这项工作。一个看起来与您的第一个示例完全相同,但需要对您的课程进行更改并且不能按照您要求的方式运行(这对您来说可能是也可能不是问题);其他行为与您所要求的完全一样,但更加冗长。你可以决定哪一个更适合你。

选项 1:添加到集合

XAML 具有用于初始化集合的神奇速记语法,使用您在第一个示例中显示的确切语法。但是,它仅在属性类型实现时才有效IList。(是的,这确实是非泛型 IList——虽然通常没什么大不了的,但 .NET 附带的所有泛型集合都实现了IList<T>IList。)

所以你可以做你的第一个例子,但前提是你的KeyActions属性被声明为实现的类型IList。例如,您可以将您的属性更改为:

public ObservableCollection<KeyAction> KeyActions { get {...} }

然后只需将多个子元素放入您的属性中,它会将它们添加到集合中:

<loc:MyType.KeyActions>
    <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
    <loc:KeyAction Action="Hide" Key="Escape" />
</loc:MyType.KeyActions>

不过,这与您所要求的不太一样,因为 XAML 不会创建集合——它会添加到现有集合中。因此,如果您选择此选项,您的类需要在其构造函数 () 中实例化集合,这样当您开始尝试向它添加元素KeyActions = new ObservableCollection<KeyAction>();时,您不会得到空引用异常。Add

选项 2:创建新集合

如果您确实需要创建一个新集合并将其分配给您的属性,那也是可行的。不幸的是,XAML2006(WPF 仍在使用的风格)仅支持整个文档的根元素上的泛型——因此您无法实例化 aList<T>并将其分配给属性。

但这没关系;您可以使用与 WPF 相同的解决方法。只需创建您自己的从泛型列表派生的非泛型类。

public class KeyActionCollection : ObservableCollection<KeyAction> {}

然后你可以在 XAML 中实例化它:

<loc:CompletionPopupView.KeyActions>
    <loc:KeyActionCollection>
        <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
        <loc:KeyAction Action="Hide" Key="Escape" />
    </loc:KeyActionCollection>
</loc:CompletionPopupView.KeyActions>

如果您选择此选项,您可以按照您的意愿声明您的财产IEnumerable<KeyAction>。只有从 XAML 填充列表时才需要自定义列表。

您甚至可以结合这两种方法:使属性为 read/write 和 type KeyActionCollection,在构造函数中对其进行实例化,然后 XAML 可以选择是使用简写语法添加到现有集合中,还是创建新集合;和运行时代码可以做出同样的选择。

于 2012-04-30T00:43:35.873 回答