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

Viewed 154

In concern to a UserControl, how would one create a dynamic number(number from property editable from Visual Studio) of labels whose text can be edited via the Visual Studio "Design" window?

Edit To clarify, I do not want the user to alter the text of labels at run time, instead only the developer who is using the control in their project is able to alter the text of labels inside the Visual Studio Designer by simply clicking on the label and changing the text. (Not the source code itself).

As it stands with what I have, when I add the labels dynamical within an override of the OnDraw event, the labels can be seen but not edited within the design window.

To provide more clarity on my question, I have provided a sample situation to demonstrate the problem. To be specific, I am creating a certain number of labels inside the Draw event like the code below. The number of labels and their location will depend on the number of labels to be drawn which is provided via a publicly accessible property in the control.

    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
    }

Below is the user control within a form from the view of the "Design" window in Visual Studio. One picture is the user control when 6 labels are to be drawn and the second picture is when 3 labels are to be drawn. Again, this number of labels is specified by a publicly accessible property in the control

enter image description here enter image description here

In the specific situation depicted from the pictures, I would like to be able to click on one of the "DEFAULT" labels and change the label "Text" property.

Version Of Visual Studio: VS 2013 (I also tried with VS 15 and 17 but got the same results) GUI Framework: Winforms

4 Answers

You could use behavior service. Here is MS's article on it. Because of how difficult this would be to implement, I advise compromising with StringCollectionEditor.

Here a very basic example of the control using a custom control.

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;
        }
    }
} 

The control has 2 properties, Title and SomeValues if you build the application with this you can drag and drop this control onto any forms. Then simply click on the control and check the property grid you will see both Title and SomeValues you can edit both there at design time. It obviously just update on redraw so just move it, stretch it or close the form and reopen to get it to show.

Anything you can change at design time can also be changed at runtime so that way you are not force to always do it this way. If you want let's say to change the different text since it's a property you can also do it by code if you want.

The answer to your question is its not possible to achieve what you are wanting.

What you are wanting is simply not possible in Visual Studio. If it was possible then there should be some .NET control that has this behavior but there is not. Though it would be nice to have labels created in the OnDraw event behave just as if the label was placed on the form in the Designer, that extra support would of have to be added into Visual Studio. As stated in a previous answer, the best work around for this is to have one collection that can modify the text for those labels in the Visual Studio Designer.

You need a develop a UserControlDesigner. All modern UI toolkit have some sort of them. My company uses DevExpress and alomst all of its complex controls have their own custom designers only available as design time.

Please refer to following article for a sample since it can become a complex topic very easily.

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

Also in stackoverflow there is another question that may help you

Custom Designer for a Control

Related