it-swarm.com.de

Rufen Sie alle Steuerelemente eines bestimmten Typs ab

Ich habe mehrere Bildboxen und muss zur Laufzeit beliebige Bilder in sie laden. Ich dachte, es wäre schön, eine Sammlung aller Bildboxen zu haben und diese dann mit einer einfachen Schleife zuzuweisen. Aber wie soll ich das machen? Oder gibt es vielleicht andere bessere Lösungen für ein solches Problem?

35
drv

Mit etwas LINQ:

foreach(var pb in this.Controls.OfType<PictureBox>())
{
  //do stuff
}

Dies kümmert sich jedoch nur um PictureBoxen im Hauptcontainer.

69
Femaref

Sie können diese Methode verwenden:

public static IEnumerable<T> GetControlsOfType<T>(Control root)
    where T : Control
{
    var t = root as T;
    if (t != null)
        yield return t;

    var container = root as ContainerControl;
    if (container != null)
        foreach (Control c in container.Controls)
            foreach (var i in GetControlsOfType<T>(c))
                yield return i;
}

Dann könntest du so etwas machen:

foreach (var pictureBox in GetControlsOfType<PictureBox>(theForm)) {
    // ...
}
23
cdhowie

Wenn Sie sich mindestens mit .NET 3.5 beschäftigen, haben Sie LINQ, was bedeutet, dass ControlCollectionIEnumerable implementiert, und Sie können Folgendes tun:

var pictureBoxes = Controls.OfType<PictureBox>();
7
Dan Tao

Eine einfache Funktion, die leicht verständlich ist, rekursiv ist und in jeder Formularsteuerung aufgerufen wird:

private void findControlsOfType(Type type, Control.ControlCollection formControls, ref List<Control> controls)
    {
        foreach (Control control in formControls)
        {
            if (control.GetType() == type)
                controls.Add(control);
            if (control.Controls.Count > 0)
                findControlsOfType(type, control.Controls, ref controls);
        }
    }

Sie können es auf mehreren Wegen aufrufen. Um die Schaltflächen zu erhalten:

List<Control> buttons = new List<Control>();
findControlsOfType(typeof(Button), this.Controls, ref buttons);

Um die Panels zu bekommen:

List<Control> panels = new List<Control>();
findControlsOfType(typeof(Panel), this.Controls, ref panels);

usw.

2
Zelkovar
    public static List<T> FindControlByType<T>(Control mainControl,bool getAllChild = false) where T :Control
    {
        List<T> lt = new List<T>();
        for (int i = 0; i < mainControl.Controls.Count; i++)
        {
            if (mainControl.Controls[i] is T) lt.Add((T)mainControl.Controls[i]);
            if (getAllChild) lt.AddRange(FindControlByType<T>(mainControl.Controls[i], getAllChild));
        }
        return lt;
    }

Hier ist eine andere Version, da die vorhandenen Versionen nicht ganz meinen Vorstellungen entsprachen. Diese funktioniert optional als Erweiterungsmethode und schließt die Überprüfung des Typs des Stamm-/übergeordneten Containers aus. Bei dieser Methode handelt es sich im Wesentlichen um eine Methode "Alle abhängigen Steuerelemente vom Typ T abrufen":

public static System.Collections.Generic.IEnumerable<T> ControlsOfType<T>(this System.Web.UI.Control control) where T: System.Web.UI.Control{
    foreach(System.Web.UI.Control childControl in control.Controls){
        if(childControl is T) yield return (T)childControl;
        foreach(var furtherDescendantControl in childControl.ControlsOfType<T>()) yield return furtherDescendantControl;
    }
}
2
scradam

Ich verwende diese generische rekursive Methode:

Die Annahme dieser Methode ist, dass, wenn das Steuerelement T ist, die Methode nicht in ihre untergeordneten Elemente schaut. Wenn Sie auch nach den Kindern suchen müssen, können Sie sie leicht entsprechend ändern.

public static IList<T> GetAllControlsRecusrvive<T>(Control control) where T :Control 
{
    var rtn = new List<T>();
    foreach (Control item in control.Controls)
    {
        var ctr = item as T;
        if (ctr!=null)
        {
            rtn.Add(ctr);
        }
        else
        {
            rtn.AddRange(GetAllControlsRecusrvive<T>(item));
        }

    }
    return rtn;
}
1
giammin

Übernimmt die Kontrolle als Container:

        private static IEnumerable<T> GetControlsOfType<T>(this Control root)
        where T : Control
    {
        if (root is T t)
            yield return t;

        if (root is ContainerControl || root is Control)
        {
            var container = root as Control;
            foreach (Control c in container.Controls)
                foreach (var i in GetControlsOfType<T>(c))
                    yield return i;
        }
    }
0

Dies ist für mich bei weitem das einfachste. In meiner Anwendung habe ich versucht, alle Textfelder in einem Panel zu löschen:

    foreach (Control c in panel.Controls)
    {
        if (c.GetType().Name == "TextBox")
        {
            c.Text = "";
        }
    }
0
Richard Martin