3

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

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Cabbage Champion
  • 1,193
  • 1
  • 6
  • 21
  • For simplicity reason if i were you i would make the label part of the actual drawing text in the picture you already generated. I would catch the usercontrol `Click` event and just check if i'm over a label and if it is i would display over a textbox to fill in and edit and on keypress check for the enter key and simply update the text property that generate that image – Franck Jun 28 '19 at 17:28
  • But that still wouldn't allow somebody from the visual studio designer to change the text of those labels? – Cabbage Champion Jun 28 '19 at 17:34
  • Just expose properties in the user control. On the `ondraw` that you probably override by the look of it, you would loop on that property (which would most likely be a collection of some sort) and draw text in the `ondraw` – Franck Jun 28 '19 at 17:38
  • Please read my edit in my question, I think what I was wanting was not communicated correctly. – Cabbage Champion Jun 28 '19 at 17:40
  • 1
    Okay now it's clear. Since you do draw manually the whole thing in the usercontrol, drawing the text instead of putting label remain the best option. You should use [Graphics.DrawString()](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.graphics.drawstring?view=netframework-4.8). To draw the text value just create a public List property in your usercontrol and fill it from the designer property window and to draw the text you pick from that list. This also allow you to modify it by code if you want. – Franck Jun 28 '19 at 17:46
  • If I do that I will be able to modify within the code only. That is not the question, I need to modify it within the designer. – Cabbage Champion Jun 28 '19 at 17:57
  • No. You can still modify from the designer. Like a `textbox` you click on it, then go on the property tab and click the property `Text` and type what you want there. Same thing here. You create a property it will show like `Text` for a `Textbox` – Franck Jun 28 '19 at 18:29
  • If you want to allow this, inside the UserControl in Design mode, don't use a raw Label. You need a Custom Control (or another UserControl) that implements this functionality. – Jimi Jun 28 '19 at 18:46
  • No. I have a n number of these labels based off of a another property. So there would be no way determine which one you would want to modify. To clarify I cant select the label that is displayed in the designer. @Franck – Cabbage Champion Jun 28 '19 at 18:47
  • @JosephPatchen check my answer. It does exactly that principle of editing through properties. It can be anything. I used a string collection for simplicity but it can be a collection of custom object. – Franck Jun 28 '19 at 18:57
  • The question is too broad. Please make it clearer, add some code and describe the expected behavior. Are you looking for an in-line editing feature for label? Or is it acceptable to edit the label text like other controls through the property editor window? – Reza Aghaei Jul 02 '19 at 05:54

4 Answers4

3

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.

Bob Vancer
  • 31
  • 3
1

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.

Franck
  • 4,438
  • 1
  • 28
  • 55
  • Ahh, I totally misunderstood you. Thank for the solution. This basically enables one to alter the values of the list via the properties tab by treating the n number of labels as a whole collection. This does solves my problem but it doesn't answer the question because I cant click on one the labels and edit them individually. Unless I missused your solution. Thank for you for your help! – Cabbage Champion Jun 28 '19 at 19:32
  • 1
    Clicking each individually this you will never be able to do that. instead you click one control and that control contain the text property for the 6 labels in the grid. – Franck Jul 02 '19 at 12:06
1

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.

Robo Maklen
  • 152
  • 1
  • 11
  • I'd say it's possible, but it's not easy to implement. Smart tag window is an example. Using Adorner, Glyph and Behavior you can show an editable text box above designer. Take a look at [Behavior Service Overview](https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/ms171826(v=vs.120)) – Reza Aghaei Jul 03 '19 at 17:53
0

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://learn.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

Erdogan Kurtur
  • 3,630
  • 21
  • 39