【问题标题】:how to create flags enum from int values and disable controls如何从 int 值创建标志枚举并禁用控件
【发布时间】:2013-05-29 17:23:17
【问题描述】:

我有一个小问题。这是我的问题的简化版本。

我有一个类,它有一个按钮列表及其名称(新建、编辑、删除)以及一个“类型”类型的对象

class test
{
    private List<Button> buttons; // 
    private Type type;

    public test(Type t)
    {
            this.type = t;
            /* some code to create the buttons from the enum. 
            got this already covered but "Restore" does not get created by intention*/
    }

    public void setButtons(int i)
    {

    }
}

类型是带有 flags 属性的枚举

[Flags] enum EnumTest{None=0, New=1, Edit=2, Delete=4, Restore=8}

我想做的是让“setButtons”方法创建一个“type”实例,将“int i”的值设置为标志值,浏览按钮列表并设置“Enabled” " 按钮的属性取决于是否引发了标志,其中按钮的“名称”属性取决于枚举中的标志名称(EnumTest 或任何其他)

我尝试了几种类似

的东西
    var enu = Enum.ToObject(type, i);

但我无法设置标志,或者我不知道如何设置。我正在考虑在创建它时使用反射。似乎“ToObject”方法不能很好地与 flags 属性配合使用。 “TryParse”似乎可以,但我不知道如何让它从“Type”动态加载。

请考虑到这是我的问题的高度简化版本,但它会保留其含义。

【问题讨论】:

  • 当您可以将EnumTest 作为参数传递时,为什么还要传递Type?
  • 因为这是一个多用途类。它不仅适用于 EnumTest,而且还必须适用于其他枚举。
  • 然后看看这里,它非常简单stackoverflow.com/questions/8447/enum-flags-attribute
  • 不相关,但如果这是 WPF,则不应在过程代码中创建或操作 UI 元素。那些令人作呕的类似 winforms 的 hack 真的不受欢迎,WPF 不能很好地处理它们。

标签: c# wpf winforms enums flags


【解决方案1】:

当调用Enum.ToObject(...) 时,System.Type 参数应该是您尝试为其检索枚举值的枚举类型。

所以,你应该这样称呼它:

EnumTest myTestVar = (EnumTest)Enum.ToObject(typeof(EnumTest), i); // i is the integer to be converted to one of the enumeration values.

注意:这仅在i 是EnumTest 中定义的值之一时才有效。例如,如果i = 6,我认为上述方法不会起作用,因为 6 不是枚举成员之一,而是它的两个成员的组合。

HTH。

更新:

嗯,我在这里看到了两件事。我想也许你可以使用泛型来解决你的问题,但是你不能使用Enum 作为泛型类型参数的类型约束。 (这是我更喜欢 Java 枚举而不是 C# 枚举的地方。实际上,您可以在 Java 枚举中定义自己的自定义方法——C# 没有骰子。)这样就结束了。

我看到的另一个问题是建议使用Enum.ToObject(Type t, int i) 方法。方法摘要清楚地写着“将指定的 32 位有符号整数转换为 an 枚举成员”[emphasis mine]。所以我认为你不能传入,比如6,并期望一个具有必要位字段集的枚举对象。 MSDN 的文档似乎支持了这一点。另请查看Enum.IsDefined 方法的文档。最后,System.Enum 有一个 HasFlag 方法,它也可能对你有用。我认为这可能是您问题的根源。我从未尝试将ToObject 与“复合”枚举值一起使用。

为什么不直接传入要启用的按钮列表:

class test
{
    private List<Button> buttons;

    public test() { /* Whatever constructor logic you need. */ }

    public void setButtons(List<Button> btnsToEnable)
    {
        btnsToEnable.ForEach(btn => btn.Enabled = true);

        // Or perhaps:
        buttons.Intersect(btnsToEnable).ToList().ForEach(btn => btn.Enabled = true);
   }
}

有多种方法可以使用 LINQ 来完成您想要的。这实际上取决于您的对象模型。希望这些想法能让您开始走上另一条适合您的场景的道路。

【讨论】:

  • 因为这是一个多用途类。它不仅适用于 EnumTest,而且还必须使用其他枚举,除非我可以根据 Type 对象强制转换它,否则这是无用的。此外,将 Flags 属性设置为 EnumTest 它应该接受 i=6 和标志并设置编辑和删除标志。
  • 啊,是的,我想ToObject 应该这样做。我不明白您对需要使用不同类型的类的评论。我会更新我的答案以反映这一点。我可能有一个适合你的想法。
  • 希望你能想出办法。它被认为是管理工具栏和激活控件的一种非常简单的方法。我实际上习惯于使用 python,并且我在 Python 中非常轻松地做了这样的事情。 C# 对于高级的东西要复杂得多。
  • 好吧,python 是一种动态语言,而 C# 不是(严格来说)。所以类型安全是最重要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多