整齐地通过XAML填充IEnumerable?

时间:2012-04-29 21:11:11

标签: xaml .net-4.0

我正在尝试从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>

我需要添加命名空间,如果可行的话,通用语法可能更加糟糕。有没有办法让第一个例子有效?

1 个答案:

答案 0 :(得分:22)

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

选项1:添加到集合

XAML使用您在第一个示例中显示的确切语法,使用魔术速记语法初始化集合。但是,它仅在属性类型实现IList时有效。 (是的,这确实是非泛型 IList - 通常不是什么大问题,.NET附带的所有通用集合都实现了IList<T>和{{1 }}。)

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

IList

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

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

这与您的要求不太相似,因为XAML不会创建集合 - 它会添加到现有集合中。因此,如果选择此选项,则您的类需要在其构造函数(<loc:MyType.KeyActions> <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" /> <loc:KeyAction Action="Hide" Key="Escape" /> </loc:MyType.KeyActions> )中实例化集合,以便在开始尝试KeyActions = new ObservableCollection<KeyAction>();元素时不会获得空引用异常。

选项2:创建新集合

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

但那没关系;您可以使用WPF执行的相同解决方法。只需创建一个属于通用列表的非泛型类。

List<T>

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

public class KeyActionCollection : ObservableCollection<KeyAction> {}

如果您选择此选项,则可以根据需要将您的媒体资源声明为<loc:CompletionPopupView.KeyActions> <loc:KeyActionCollection> <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" /> <loc:KeyAction Action="Hide" Key="Escape" /> </loc:KeyActionCollection> </loc:CompletionPopupView.KeyActions> 。自定义列表仅用于从XAML填充列表。

您甚至可以结合使用两种方法:使属性读/写并且类型为IEnumerable<KeyAction>,在构造函数中实例化它,然后XAML可以选择是使用简写语法添加到现有集合,还是创建新系列;和运行时代码可以做出相同的选择。