gpt4 book ai didi

.net - 带有多个零值问题的标志枚举 (TextFormatFlags)

转载 作者:行者123 更新时间:2023-12-04 07:00:53 27 4
gpt4 key购买 nike

在尝试编写自定义控件时,我遇到了 System.Windows.Forms.TextFormatFlags 枚举与 Visual Studio (2005/2008) 编辑器结合使用的问题。这个问题的原因似乎来自这个枚举有多个映射到零值的成员。选择这些成员中的任何一个(GlyphOverhangPadding、Left、Default、Top)都会导致编辑器将属性设置为

this.customControl.TextFormatFlags = System.Windows.Forms.TextFormatFlags.GlyphOverhangPadding;

代码按预期编译。但是,从编辑器的属性网格中选择任何非零成员(例如“Right”)会导致以下结果:
this.customControl.TextFormatFlags = System.Windows.Forms.TextFormatFlags.Left, Default, Top, Right;

显然这不会编译。选择多个非零成员(通过 UITypeEditor,例如“Right | Bottom”)会导致以下结果:
this.customControl.TextFormatFlags = ((System.Windows.Forms.TextFormatFlags)((System.Windows.Forms.TextFormatFlags.Left, Default, Top, Right | System.Windows.Forms.TextFormatFlags.Left, Default, Top, Bottom)));

如您所见,编辑器将四个零值成员中的三个添加到任何选定项。

如果您希望重现此问题:
  • 在 Visual Studio 2005/2008 中创建一个新项目(Windows 窗体应用程序)
  • 将自定义控件添加到项目中。
  • 将私有(private)字段和公共(public)属性添加到新类:

    私有(private) TextFormatFlags tff = TextFormatFlags.Default;

    公共(public) TextFormatFlags TFFProperty
    {
    得到 { 返回 this.tff; }
    设置 { this.tff = 值; }
    }
  • 编译代码
  • 在设计器中打开 Form1 并将 CustomControl1 添加到它
  • 代码编译良好
  • 现在在编辑器的 PropertyGrid
  • 中打开 CustomControl1 的属性
  • 您应该在“杂项”部分下看到 TFFProperty
  • 该属性提供多个值,其中大部分包含逗号。
  • 选择任何带逗号的值(例如“Left、Default、Top、Horizo​​ntalCenter)会导致无法编译的代码

  • 如果您使用 Flags 属性创建自己的枚举并添加多个映射到零的成员(这是一种格式错误的标志枚举?),也会发生同样的情况。我已经验证这不是我正在使用的 UITypeEditor 的错误(不使用 UITypeEditor 也会出现同样的问题)。我试图用转换器来规避这个问题,但到目前为止没有成功。如果有人对如何解决这个问题有任何想法,我会很高兴听到他们的声音。

    最佳答案

    我检查了 System.ComponentModel.Design.Serialization 中的各个类使用 Reflector 的命名空间,我认为 CodeDom 序列化程序有点顽皮。

    枚举由 EnumCodeDomSerializer.Serialize 处理,其目的是获取一个枚举并将其转换为 System.CodeDom.CodeExpression代表您在设计器文件中看到的对象。

    此方法正确使用CodeBinaryOperatorExpression处理|表达的方面。但是,对于单个枚举值,它使用 Enum.ToString通过 EnumTypeConverter并将生成的字符串直接粘贴到表达式树中。

    我认为 Enum.ToString 是你所看到的最终原因:

    If multiple enumeration members have the same underlying value and you attempt to retrieve the string representation of an enumeration member's name based on its underlying value, your code should not make any assumptions about which name the method will return.



    诚然, Enum.ToString 上的 MSDN 页面没有谈论逗号,但依赖 Enum.ToString 的输出似乎仍然不安全是一个有效的 C# 表达式。

    我不确定这对您的控制意味着什么:
  • 显然,您可以定义自己的替换 TextFormatFlags并且没有重复的零标志
  • 您可以使用自定义类型转换器破解它,也许可以转换为 InstanceDescriptor .这使您可以更好地控制设计器生成的代码中出现的内容。
  • 你可能会暴露一个 int给设计器序列化程序,但 TextFormatFlags到属性网格

  • 编辑: The comma-separated list behaviour of Enum.ToString is in fact documented

    关于.net - 带有多个零值问题的标志枚举 (TextFormatFlags),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1862614/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com