【问题标题】:Windows Forms Designer upset by a control with a nullable propertyWindows 窗体设计器因具有可为空属性的控件而感到不安
【发布时间】:2010-09-08 13:31:05
【问题描述】:

我在 C# .NET 中有一个“数字文本框”,它只不过是文本框的派生,并添加了一些逻辑来防止用户输入任何非数字内容。作为其中的一部分,我添加了一个double?(或Nullable<double>)类型的Value 属性。支持用户不输入任何内容的情况下可以为空。

该控件在运行时工作正常,但 Windows 窗体设计器似乎不太喜欢处理它。将控件添加到窗体时,InitializeComponent() 中会生成以下代码行:

this.numericTextBox1.Value = 1;

记住“值”的类型为Nullable<double>。每当我尝试在设计器中重新打开表单时,都会生成以下警告:

Object of type 'System.Int32' cannot be converted to type 'System.Nullable`1[System.Double]'.

因此,在我手动删除该行并重新构建之前,无法在设计器中查看表单 - 之后,只要我保存任何更改,它就会重新生成。烦人。

有什么建议吗?

【问题讨论】:

  • Ralch's answer 从技术角度来看是最好的解决方案,也是人们最有可能寻找的解决方案。

标签: c# winforms nullable


【解决方案1】:

将该属性上的DefaultValue attribute 设置为 new Nullable(1) 是否有帮助?

[DefaultValue(new Nullable<double>(1))]  
public double? Value ...

【讨论】:

  • 如果设计器中的值发生变化,则不会。
【解决方案2】:

或者,如果您根本不希望设计器添加任何代码...将其添加到属性中。

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

【讨论】:

    【解决方案3】:

    Visual Studio 2008 中似乎存在问题。您应该创建自定义 CodeDomSerializer 来解决它:

    public class CategoricalDataPointCodeDomSerializer : CodeDomSerializer
    {
        public override object Deserialize(IDesignerSerializationManager manager, object codeObject)
        {
            CodeStatementCollection collection = codeObject as CodeStatementCollection;
    
            if (collection != null)
            {
                foreach (CodeStatement statement in collection)
                {
                    CodeAssignStatement codeAssignment = statement as CodeAssignStatement;
    
                    if (codeAssignment != null)
                    {
                        CodePropertyReferenceExpression properyRef = codeAssignment.Left as CodePropertyReferenceExpression;
                        CodePrimitiveExpression primitiveExpression = codeAssignment.Right as CodePrimitiveExpression;
    
                        if (properyRef != null && properyRef.PropertyName == "Value" && primitiveExpression != null && primitiveExpression.Value != null)
                        {
                            primitiveExpression.Value = Convert.ToDouble(primitiveExpression.Value);
                            break;
                        }
                    }
                }
            }
    
            return base.Deserialize(manager, codeObject);
        }
    }
    

    那么你应该在你的类上使用DesignerSerializer 属性来应用它。

    【讨论】:

      猜你喜欢
      • 2010-11-23
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 2014-10-03
      • 2011-09-03
      • 1970-01-01
      相关资源
      最近更新 更多