简体   繁体   中英

A Collection *OF* DataGridViews? Manipulating all DataGridViews at Once

I'm continuing to work on a few VSTO's and I was wondering if there was a way to refer to all the datagridviews in a class at once. I can't seem to figure out what the container should be, and I can't seem to add them to arrays/other containers?

The psudo code for what I'm tring to do would be something like:

For Each datagridview in Globals.MyUserControl
   'change some datagridview property ie:
   datagridview1.ReadOnly = True
Next

I would be hapy in C# or VB.net, or really any explanation of if this can or can't be done. At the moment I'm manually setting it for all the different datagridviews, as that number grows, I would like a way to hit them all at once.

Still trying to work on the solutions below, another way I've tried this that doesn't work:

    For Each ctl In Me.Controls
        If TypeOf ctl Is DataGridView Then
            ctl.ReadOnly = True
            ctl.AllowUserToDeleteRows = False
        End If
    Next

But I don't know why that doesn't work.

You can use a foreach loop:

foreach (DataGridView ctrl in Globals.MyUserControl.Controls)
    ctrl.ReadOnly = true;

If you're expecting any non-datagridview controls in the controls collection that you don't want to set to read-only, then instead of a single statement, you can check the type of ctrl.

foreach (Control ctrl in Globals.MyUserControl.Controls)
    if(ctrl is DataGridView) ctrl.ReadOnly = true;

Using LINQ, you can do this:

Globals.MyUserControl.Controls.Cast<Control>().ToList().ForEach((ctrl) => { if (ctrl is DataGridView) ((DataGridView)ctrl).ReadOnly = true; });

Or if all your controls are known to be DataGridView controls, then you can do this:

Globals.MyUserControl.Controls.Cast<DataGridView>().ToList().ForEach(ctrl => ctrl.ReadOnly = true);

To find child controls inside other controls, define a recursive method and call that:

    private static void FindControlsRecursively(Control.ControlCollection collection)
    {
        foreach (Control ctrl in collection)
        {
            if (ctrl is DataGridView)
                ((Label)ctrl).ReadOnly = true;
            else if (ctrl.Controls.Count > 0)
                FindControlsRecursively(ctrl.Controls);
        }
    }

Then call it with the controls of your user control from your user control:

FindControlsRecursively(this.Controls);

Something like this should work:

    For Each ctl In Me.Controls.OfType(Of DataGridView)()
        ctl.ReadOnly = True
        ctl.AllowUserToDeleteRows = False
    Next

Or C#

        foreach (DataGridView ctrl in this.Controls.OfType<DataGridView>())
        {
            ctrl.ReadOnly = true;
            ctrl.AllowUserToDeleteRows = false;
        }

This loops through only the DataGridViews in the form.

Additionally you can add them to a List(Of DataGridView), if necessary

Another option is to declare a class that inherits DataGridView, set the properties you want, and declare new datagridviews of this type to add to your form(s).

I'm not sure if I should put this in the answer, or if Tombola wants to move it to his, but here was my solution. The problem was that all my datagridviews were nested on tab pages in a tab control. To get it to work I used:

    For Each tabpg In TabControl1.TabPages()
        For Each ctl In tabpg.Controls  'note, was not able to use 'OfType here, but had to drop to the If statement or I ran into runtime errors.
            If TypeOf ctl Is DataGridView Then
                ctl.ReadOnly = True
                ctl.AllowUserToDeleteRows = False
            End If
        Next
    Next

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM