【发布时间】:2010-11-16 06:03:27
【问题描述】:
我一直在疯狂地将一个组合框绑定到一个类的枚举类型属性,其中枚举本身是在同一个类中声明的。
我正在尝试遵循此处提供的答案 (wpf combobox binding to enum what i did wrong?) 具体来说,我正在使用建议的 MarkupExtension 代码和匹配的 xaml 代码。
我的工作代码是:
在单独的文件中定义枚举。
namespace EnumTest
{
public enum TestEnum {one, two, three, four };
}
使用 Enum 的类(请注意,已删除 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 类中定义 Enum within,并放弃在全局范围内定义 Enum。像这样:
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}}"
...
/>
但这(有点)对我不起作用。当我进行干净的构建时,我在 VS 2008 状态栏上收到“构建成功”消息,但我也收到在 xaml 中报告的错误
Type 'Test+TestEnum' was not found.
但代码按预期运行!
但这意味着 xaml 设计器将不会加载。因此,在清除 xaml 错误之前,我有点搞砸了 wpf 工作。
我现在想知道这是否是 VS 2008 SP1 的问题,而不是我的问题。
编辑
- 使我的问题陈述更加明确。
- 尝试了 Joel 的第一个解决方案,但我最终发现代码运行 和 2 个 xaml 错误
- 尝试了 Joel 的第二个解决方案,该解决方案直接开箱即用 - 所以我将使用那个解决方案!
注意事项 我从中获得 MarkupExtension 代码的 SO 问题对 xaml 使用了这种语法:
<ComboBox ItemsSource="{w:EnumValues w:TestEnum}"/>
当我使用它时,我得到一个编译错误,说没有 EnumValues 构造函数需要 1 个参数。我做了一些谷歌搜索,这似乎是 VS 中的一个错误。我正在使用 VS 2008 SP1。我确实看到了一些暗示它在 VS 2010 beta 中的 cmets。无论如何,这就是我使用
的 xaml 语法的原因<ComboBox ItemsSource="{w:EnumValues EnumType=w:TestEnum}"/>
因为这个语法有效!
【问题讨论】:
-
关于构造函数的错误,它只发生在设计器中。否则它应该可以正常工作。为避免此错误,请在单独的程序集中定义标记扩展
-
@Thomas:我已经忘记了设计师是如何对何时/何地构建什么类型以及如何实例化它们感到愤怒的。
-
@Joel - wpf 新手程序员怎么知道这种事情?知道将一个类放在一个单独的程序集中以满足构建工具的一部分是相当模糊的恕我直言。但我会继续努力,直到我得到合理的理解。再次感谢。
-
@Thomas - 感谢您的提示。这不是我曾经考虑过的事情——即使在谷歌上搜索了那个特定问题之后也是如此。
-
@Peter:是的,它很模糊。不过,它对我来说并不经常出现。我正在尝试找到一个解释 Cider 如何实例化事物的链接,因为我只记得有关基类的内容。
标签: wpf class combobox enums nested