在 OnDraw 事件中动态创建标签并可从 Visual Studio Designer 编辑

Lable dynamical created in OnDraw event and editable from Visual Studio Designer

关于 UserControl,如何创建一个动态数字(来自 属性 的数字可编辑来自 Visual Studio)的标签,其文本可以通过 Visual Studio "Design" window?

Edit 澄清一下,我希望用户更改运行 时的标签,只有在其项目中使用该控件的开发人员才能通过简单地单击来更改 Visual Studio Designer 中的标签文本在标签上并更改文本。 (不是源代码本身)。

就我所拥有的而言,当我在 OnDraw 事件的覆盖范围内添加动态标签时,可以看到标签但无法在设计中编辑 window。

为了更清楚地说明我的问题,我提供了一个示例情况来演示问题。具体来说,我在 Draw 事件中创建了一定数量的标签,如下面的代码所示。标签的 数量 及其 位置 将取决于要绘制的标签数量,这是通过可公开访问的 属性 在控件。

    public void CalledFromDrawMethod (string strElement, UserControl ucParentControl, Point pLoc)
    {
        var lblChild = new Label();
        lblChild.Text = strElement;
        lblChild.Location = pLoc;
        ucParentControl.Controls.Add(lblChild);// Add the label
    }

下面是 Visual Studio 中 "Design" window 视图中表单内的用户控件。一张图是绘制6个标签时的用户控件,第二张图是绘制3个标签时的用户控件。同样,此标签数量由控件

中的可公开访问的 属性 指定

在图片描述的具体情况下,我希望能够点击其中一个 "DEFAULT" 标签并更改标签 "Text" 属性.

Version Of Visual Studio: VS 2013(我也尝试过 VS 15 和 17,但得到了相同的结果) GUI 框架: Winforms

这里是一个使用自定义控件的非常基本的控件示例。

public class ExampleCustomControl : Control
{
    public string Title { get; set; } = "";

    [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", typeof(System.Drawing.Design.UITypeEditor))]
    public StringCollection SomeValues { get; set; } = new StringCollection();
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        // grab the graphics object
        var g = e.Graphics;

        // draw the title property
        g.DrawString(Title, Font, Brushes.Blue, 0, 0);

        // will alter positions
        var y = 10;

        // for each value set in the properties
        foreach (var value in SomeValues)
        {
            // draw the property value
            g.DrawString(value, Font, Brushes.Red, 0, y);

            // move the position for the next text
            y += 10;
        }
    }
} 

该控件有 2 个属性,TitleSomeValues 如果您使用它构建应用程序,您可以将此控件拖放到任何窗体上。然后只需单击控件并选中 属性 网格,您将看到 TitleSomeValues,您可以在设计时在那里编辑它们。它显然只是在重绘时更新,所以只需移动它、拉伸它或关闭表单并重新打开它即可显示。

您可以在设计时更改的任何内容也可以在运行时更改,这样您就不会被迫总是这样做。如果你想更改不同的文本,因为它是 属性 如果你愿意,你也可以通过代码来完成。

你的问题的答案是不可能实现你想要的。

您想要的在 Visual Studio 中根本不可能实现。如果可能的话,应该有一些 .NET 控件具有这种行为,但没有。虽然在 OnDraw 事件中创建标签的行为就像在设计器中将标签放置在窗体上一样很好,但必须在 Visual Studio 中添加额外的支持。如前一个答案所述,最好的解决方法是拥有一个可以修改 Visual Studio Designer 中这些标签文本的集合。

您需要开发一个 UserControlDesigner。所有现代 UI 工具包都有一些。我的公司使用 DevExpress,几乎所有的复杂控件都有自己的自定义设计器,仅在设计时可用。

请参考以下文章的示例,因为它很容易成为一个复杂的主题。

https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/creating-a-wf-control-design-time-features

同样在 Whosebug 中还有一个问题可能对您有所帮助

Custom Designer for a Control

您可以使用行为服务。 Here是MS的文章就可以了。由于实施起来有多么困难,我建议妥协 StringCollectionEditor.