整齐地通过XAML填充IEnumerable?

Max*_*Max 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>
Run Code Online (Sandbox Code Playgroud)

现在,这会导致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>
Run Code Online (Sandbox Code Playgroud)

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

Joe*_*ite 23

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

选项1:添加到集合

XAML使用您在第一个示例中显示的确切语法,使用魔术速记语法初始化集合.但是,它仅在属性类型实现时有效IList.(是的,这是真正的非通用 IList -通常不是什么大不了的,虽然,所有的泛型集合与.NET一起实现这两个IList<T>IList.)

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

public ObservableCollection<KeyAction> KeyActions { get {...} }
Run Code Online (Sandbox Code Playgroud)

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

<loc:MyType.KeyActions>
    <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
    <loc:KeyAction Action="Hide" Key="Escape" />
</loc:MyType.KeyActions>
Run Code Online (Sandbox Code Playgroud)

这不像你要求的那样,因为XAML不会创建新的集合 - 它会添加到现有集合中.因此,如果选择此选项,则您的类需要在其构造函数(KeyActions = new ObservableCollection<KeyAction>();)中实例化集合,以便在开始尝试使用Add元素时不会获得空引用异常.

选项2:创建新集合

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

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

public class KeyActionCollection : ObservableCollection<KeyAction> {}
Run Code Online (Sandbox Code Playgroud)

然后你可以在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>
Run Code Online (Sandbox Code Playgroud)

如果您选择此选项,则可以按照IEnumerable<KeyAction>您的意愿保留您的财产.自定义列表仅用于从XAML填充列表.

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