1

In Visual Studio 2022, in designer, on a form, I have many different types of controls like buttons, labels and others.

How do I select all buttons, for instance?

What I am doing now is pressing Shift key and then selecting the buttons one by one, which is taking to much time.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
DotNet Developer
  • 2,973
  • 1
  • 15
  • 24
  • 1
    There's no magic way to select controls of just one type. You can either click and drag to select all controls in a box and/or multi-select one by one, as you're doing. I can't imagine how many controls there would need to be on a form for that to take too much time so I can't help but be concerned about your design. – jmcilhinney Jan 31 '23 at 03:09
  • Maybe there are some Add-ins? – DotNet Developer Jan 31 '23 at 03:11
  • There may be, but asking for recommendations for third-party tools is one of the explicit reasons for closing questions on this site. – jmcilhinney Jan 31 '23 at 03:16
  • Note that you can click and drag and the deselect the ones you don't want, so maybe that would be faster than selecting the ones you do want, if `Buttons` are in the majority. – jmcilhinney Jan 31 '23 at 03:17
  • In my project I have 14 buttons and 20 labels, for instance, and some other controls of other types. Selecting only buttons the way you are describing is slowing down my work. – DotNet Developer Jan 31 '23 at 03:20
  • Can you post a screenshot of your form design? Like I said, you can click and drag so, depending on the layout, it may be as simple as click and drag to select one block, then Ctrl+click and drag to add another block to the selection. Like I said, there's no way to select just a specific type of control so you have to use the options available. Again, though, selecting 14 `Buttons` individually would take about 3 or 4 seconds max. How often are you selecting them that this is actually a problem? – jmcilhinney Jan 31 '23 at 03:56
  • I imagine that you'd be able to create your own VS extension to do this sort of thing so maybe you should look into creating VS extensions. If this sort of thing is really a drain on your time then that would be an investment. – jmcilhinney Jan 31 '23 at 03:57
  • I remember AutoDesk's AutoCAD software had similar functionality which enables selecting objects by some same attributes. It was very handy. – DotNet Developer Jan 31 '23 at 04:07
  • In addition to the above methods, you can also use the GroupBox in the toolbox. Put the controls you want to drag in batches into the GroupBox, and then drag the GroupBox directly. – wenbingeng-MSFT Jan 31 '23 at 07:36

1 Answers1

1

You can create a new Visual Studio extension which adds a new menu, or a new toolbar, or a new button to an existing window. Then using IDesignerHost and INestedContainer, get the selectable components, and filter them to get list of buttons, then using ISelectionService select them.

You can find all the building blocks of the solution here and there, for example in my following posts:

But to keep it simple to use and simple for test, I'll use a different solution that I used here, which is adding a new designer verb to context menu, using a base class.

enter image description here

To do so, Create a BaseForm class deriving from Form. Then each form which drives from this class will have above functionality that you see in the animation. Here is the code of the base form:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;

public partial class BaseForm : Form
{
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        if (DesignMode && Site != null)
        {
            var host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (host != null)
            {
                var designer = (DocumentDesigner)host.GetDesigner(this);
                if (designer != null)
                {
                    designer.ActionLists.Clear();
                    designer.ActionLists.Add(
                        new MyActionList(host, designer));
                }
            }
        }
    }

    public class MyActionList : DesignerActionList
    {
        IDesignerHost host;
        ControlDesigner designer;
        public MyActionList(IDesignerHost host,
            ControlDesigner designer) : base(designer.Component)
        {
            this.host = host;
            this.designer = designer;
        }
        private void SelectAllButtons()
        {
            var buttons = GetSelectableComponents(host).OfType<Button>().ToList();
            var svc = host.GetService(typeof(ISelectionService)) as ISelectionService;
            if (svc != null)
            {
                svc.SetSelectedComponents(buttons);
            }
        }
        public override DesignerActionItemCollection GetSortedActionItems()
        {
            var items = new DesignerActionItemCollection();
            var category = "New Actions";
            items.Add(new DesignerActionMethodItem(this, "SelectAllButtons",
                "Select all buttons", category, true));
            return items;
        }
        private List<IComponent> GetSelectableComponents(IDesignerHost host)
        {
            var components = host.Container.Components;
            var list = new List<IComponent>();
            foreach (IComponent c in components)
                list.Add(c);
            for (var i = 0; i < list.Count; ++i)
            {
                var component1 = list[i];
                if (component1.Site != null)
                {
                    var service = (INestedContainer)component1.Site.GetService(
                        typeof(INestedContainer));
                    if (service != null && service.Components.Count > 0)
                    {
                        foreach (IComponent component2 in service.Components)
                        {
                            if (!list.Contains(component2))
                                list.Add(component2);
                        }
                    }
                }
            }
            return list;
        }
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398