我一直在尝试将一个枚举类型的属性绑定到ComboBox上,这个枚举本身是在同一个类中声明的。
我试着去遵循这里提供的答案 (wpf combobox binding to enum what i did wrong?)。具体来说,我正在使用建议的MarkupExtension代码和对应的XAML代码。
我的代码已经可以正常工作:
将枚举定义在单独的文件中。
namespace EnumTest
{
public enum TestEnum {one, two, three, four };
}
使用枚举的类(注意,已经删除propertyChanged代码以简化事情):
namespace EnumTest
{
public class Test : INotifyPropertyChanged
{
private TestEnum _MyVar;
public TestEnum MyVar {
get { return _MyVar; }
set
{
_MyVar = value;
OnPropertyChanged("MyVar");
}
}
public Test()
{
_MyVar = TestEnum.three;
}
}
}
使用该类的程序文件:
namespace EnumTest
{
public partial class Window1 : Window
{
Test _oTest = new Test();
public Window1()
{
InitializeComponent();
cmbBox.DataContext = _oTest;
}
}
}
用于显示枚举的扩展方法
namespace EnumTest
{
[MarkupExtensionReturnType(typeof(object[]))]
public class EnumValuesExtension : MarkupExtension
{
public EnumValuesExtension()
{
}
public EnumValuesExtension(Type enumType)
{
this.EnumType = enumType;
}
[ConstructorArgument("enumType")]
public Type EnumType { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (this.EnumType == null)
throw new ArgumentException("The enum type is not set");
return Enum.GetValues(this.EnumType);
}
}
}
以下是用于显示数据的XAML代码:
<Window x:Class="EnumTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:EnumTest"
Title="Window1" Height="300" Width="300">
<Grid>
<ComboBox Name="cmbBox"
Height="20"
Width="80"
ItemsSource="{Binding Source={w:EnumValues EnumType=w:TestEnum}}"
SelectedItem="{Binding Path=MyVar}"
/>
</Grid>
</Window>
上面的方法都很好,但我想要在Test类内部定义枚举,不再将枚举定义在全局作用域中。像这样:
namespace EnumTest
{
public class Test : INotifyPropertyChanged
{
// Declare Enum **INSIDE** the class
public enum TestEnum {one, two, three, four };
private TestEnum _MyVar;
public TestEnum MyVar {
get { return _MyVar; }
set
{
_MyVar = value;
OnPropertyChanged("MyVar");
}
}
public Test()
{
_MyVar = TestEnum.three;
}
}
}
我所提到的SO问题暗示匹配xaml语法如下:
<ComboBox Name="cmbBox"
...
ItemsSource="{Binding Source={w:EnumValues EnumType=w:Test+TestEnum}}"
...
/>
但这对我来说(有点)不起作用。当我进行清理构建时,Visual Studio 2008 状态栏会显示“构建成功”的消息,但同时我也会收到在 XAML 中报告的错误。
Type 'Test+TestEnum' was not found.
但代码按预期运行!
然而,这意味着XAML设计器将不会加载。因此,在我能够解决XAML错误之前,我无法进行更多的WPF工作。
我现在想知道这是否是VS 2008 SP1的问题,而不是我的问题。
编辑
- 使我的问题陈述更明确。
- 尝试了Joel的第一种解决方案,但最终代码可以运行和2个XAML错误。
- 尝试了Joel的第二种解决方案,并且直接奏效,所以我选择它!
注:我从SO问题中获取了MarkupExtension代码,并使用了这种语法样式的XAML:
<ComboBox ItemsSource="{w:EnumValues w:TestEnum}"/>
当我使用这个时,编译错误显示没有EnumValues构造函数接受1个参数。我尝试了一些搜索,似乎这是一个VS的错误。我正在使用VS 2008 SP1。我看到一些评论提到这在VS 2010 beta中有过类似问题。无论如何,这就是我使用xaml语法的原因。
<ComboBox ItemsSource="{w:EnumValues EnumType=w:TestEnum}"/>
这个语法是可行的!