我在ViewModel类上定义了一个名为
的静态属性static member GetColumnTypes = FSharpType.GetUnionCases typeof<ColumnType>
其中ColumnType是普通联合类型
type ColumnType = T_Link of TableName | T_Real | T_Bool | T_Int | T_String
我不理解XAML中的逻辑在以下场景中绑定到这样的集合:
<UserControl.Resources>
<ObjectDataProvider x:Key="typelist" MethodName="GetColumnTypes" ObjectType="{x:Type local:MarkupViewModel}"/>
<local:MarkupViewModel x:Key="defaultVM" d:IsDataSource="True"/>
</UserControl.Resources>
//1-WORKS
<ComboBox ItemsSource="{Binding Source={StaticResource defaultVM}, Path=GetColumnTypes}"></ComboBox>
//2-DOES NOT WORK
<ComboBox ItemsSource="{Binding Source={StaticResource typelist}}"></ComboBox>
//3-DOES NOT WORK
<ComboBox ItemsSource="{Binding Source={x:Type local:MarkupViewModel}, Path=GetColumnTypes}"></ComboBox>
//4-WORKS
<ComboBox ItemsSource="{Binding Path=GetColumnTypes}" />
defaultVM
的静态资源正在使用无参数构造函数创建一个对象。在这个对象上,没有方法GetColumnTypes!GetColumnTypes
。如果我看example getting Enum values,它似乎正在发生的事情。我的情况是jsut更简单,因为它没有参数除了这些问题之外,我觉得它非常黑盒魔术,而且我看到的关于绑定过程的信息很少。
说清楚的最佳方法是什么? 是否可能有一些调试工具可用于绑定过程?
答案 0 :(得分:3)
有两件事需要清楚:
首先,在XAML中,您可以通过该类型的实例访问静态成员。 您也可以在VB.NET中执行此操作,例如使用以下代码:
Dim x = New MarkupViewModel()
x.GetColumnTypes
MarkupViewModel.GetColumnTypes
最后两行是等效的。实际上,编译器将第一行重写为第二行。 XAML也是一样的。如果您有实例,则可以通过与实例成员相同的语法访问静态成员。 (其他语言,如C#和F#,不允许这种语法)。
其次,ObjectDataProvider
调用方法,但GetColumnTypes
是属性。如果您已将其定义为static member GetColumnTypes() = ...
,我希望它可以正常工作。
然而,这些方法都不是真正理想的。您要做的是使用x:Static标记扩展名。这就是它的设计目标。
在命名空间定义中(在XAML文件的最顶层标记中),写下这样的内容:
<UserControl [...] xmlns:local="clr-namespace:Your.Namespace">
然后让组合框声明它的项目如下:
<ComboBox ItemsSource="{x:Static local:MarkupViewModel.GetColumnTypes}">
(虽然如果你将它保留为属性而不是功能,你当然应该将其重命名为ColumnTypes
而不是GetColumnTypes
)
哦,至于诊断绑定错误,可以通过Visual Studio Options > Debugging > Output Window > WPF Trace Settings
获得大量调试信息,这可以将大量信息转储到输出窗口。但是,如果你不太了解WPF,它们可能有点难以理解。一个优秀的通用WPF实用程序是Snoop,这有很多其他原因,但它也可以显示绑定错误信息。