【问题标题】:Can't edit Point[] or List<Point> at design time无法在设计时编辑 Point[] 或 List<Point>
【发布时间】:2016-07-25 06:41:33
【问题描述】:

我正在创建自定义控件,该控件将从点列表(或数组)中绘制形状。 我已经完成了基本的绘图功能,但现在我在 Visual Studio 中的设计时支持上苦苦挣扎。

我创建了两个属性:

private Point _point;
public Point Point
{
    get { return _point; }
    set { _point = value; }
}

private Point[] _points;
public Point[] Points
{
    get { return _points; }
    set { _points = value; }
}

如下屏幕所示,Point 是可编辑的,但 Points 的编辑器不起作用。对于每个属性,我都会收到错误 Object does not match target type.

如果我将 Point 更改为 MyPoint(具有 X、Y 属性的自定义类),编辑器可以正常工作,但我不想创建不需要的额外类,因为编辑器在应有的时候无法工作。

我的问题是:我可以使用数组或点列表作为公共属性并为其提供设计时支持吗?

【问题讨论】:

标签: c# winforms user-controls windows-forms-designer design-time


【解决方案1】:

您可以创建一个派生CollectionEditor 的自定义集合编辑器并将typeof(List&lt;Point&gt;) 设置为集合类型,还可以为Point 注册一个新的TypeConverterAttribute

// Add reference to System.Design
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.ComponentModel.Design;

public class MyPointCollectionEditor : CollectionEditor
{
    public MyPointCollectionEditor() : base(typeof(List<Point>)) { }
    public override object EditValue(ITypeDescriptorContext context,
        IServiceProvider provider, object value)
    {
        TypeDescriptor.AddAttributes(typeof(Point), 
            new Attribute[] { new TypeConverterAttribute() });
        var result = base.EditValue(context, provider, value);
        TypeDescriptor.AddAttributes(typeof(Point), 
            new Attribute[] { new TypeConverterAttribute(typeof(PointConverter)) });
        return result;
    }
}

然后将其注册为您的List&lt;Point&gt; 的编辑器就足够了:

using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;

public class MyClass : Component
{
    public MyClass() { Points = new List<Point>(); }

    [Editor(typeof(MyPointCollectionEditor), typeof(UITypeEditor))]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public List<Point> Points { get; private set; }
}

【讨论】:

  • 谢谢。这工作正常。我对Designer.cs 文件有疑问。添加点后,它们在 Designer.cs 中可见为 this.shape1.Points.Add(((System.Drawing.Point)(resources.GetObject("shape1.Points")))); 我可以更改它,以便在 Designer 中看到值而不是资源?我必须为它创建某种转换器吗?
  • 关闭对话框后(在EditValue 之后)再次将转换器设置为PointConverter。我编辑了帖子。
  • 太棒了!谢谢你的帮助。
【解决方案2】:

如果您可以添加对PresentationCoreWindowsBase 的引用,则可以使用System.Windows.Media.PointCollection

private System.Windows.Media.PointCollection _points = new System.Windows.Media.PointCollection();
public System.Windows.Media.PointCollection Points
{
    get { return _points; }
    set { _points = value; }
}

希望能有所帮助。

【讨论】:

  • 感谢您的建议,我会将这个问题留待一段时间。您的解决方案是一个选项,但需要两个依赖项。我想尽量减少它们,所以也许可以选择使用 Point 而不是 Points 但使用内置集合
  • @Misiu,不用担心打开它,我很好奇是否还有另一种不涉及自定义类或自定义容器的方法。但出于好奇,您的目标是什么版本的 .NET 框架? PresentationCoreWindowsBase 是自 3.0 以来 .NET 框架的一部分,因此添加对它们的引用并不像添加对 XNA 框架的引用那样添加依赖项将是.. ?
猜你喜欢
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 2021-01-13
相关资源
最近更新 更多