[c#] Farbe aller Buttons mit möglichst wenig Text ändern

csharpstarter

Grünschnabel
Hallo Alle zusammen,
wie man an meinem Namen unschwer erkennen kann habe ich gerade angefangen mit c# zu arbeiten....

Derzeit entwerfe ich ein kleines Programm mit mehreren Textboxen und Buttons.
Die Hintergrundfarbe zu setzen war kein Problem, auch die Farbe einzelner Buttons ändern stellt kein Problem dar.
Aber, die Buttons sollen alle die selbe Farbe haben und daher wollte ich fragen ob es eine Möglichkeit gibt, allen Buttons auf einmal zu sagen welche Farbe sie annehmen sollen****?

Ich habe das Problem bis jetzt so gelöst:

Color Button = Color.FromArgb( xx,xx,xx);
this.btnXXX.BackColor = Button;

Aber ich habe natürlich keine lust jedem Button einzeln zu sagen das er die Farbe annehmen soll, sondern möchte wenn möglich über einen Befehl die Farbe aller Buttons gleich zu setzen (z.B. allButtons.BackColor = Button;)
Wenn es eine Möglichkeit gibt so etwas zu tun dann sagt mir bitte bescheid.

Vielen Dank im Vorraus,

chsharpstarter
 
Hallo,

du könntest es mit einer Schleife über alle Controls machen. Ist das Control ein Button, dann änderst du die Farbe.
C#:
foreach(Control c in Controls)
{
    Button b = c as Button;
    
    if( b !=null )
    {
        b.BackColor = Color.FromArgb( xx,xx,xx);
    }
 }
Gruß
MCoder
 
Hallo,

der Code funktioniert zwar, ist aber auch nicht ganz ohne, weil du hier versuchst das aktuelle Control in einen Button zu quetschen und erst dann guckst, ob das auch funktioniert hat.
Besser ist, vorher zu gucken, ob man überhaupt einen Button am Wickel hat und nur dann darauf zu reagieren.
C#:
foreach (Control c in Controls)
{
    if (c.GetType() == typeof(Button))
    {
        c.BackColor = Color.FromArgb(255, 204, 0);
    }
}
Diese Variante hat außerdem noch den Vorteil, dass du nicht noch einen verwaisten Button im Speicher rumfliegen hast.
 
Hallo,

der Code funktioniert zwar, ist aber auch nicht ganz ohne, weil du hier versuchst das aktuelle Control in einen Button zu quetschen und erst dann guckst, ob das auch funktioniert hat.
Das ist der Weg den z.B.: Microsoft in der MSDN-Library vorschlägt: siehe hier
Aber davon abgesehen ist dein Code funktional nicht gleich wie der oben beschriebene, da du nur Controls findest die Buttons sind, aber keine die von Button abgeleitet sind. Daher wenn du schon sowas schreiben willst dann bitte mit dem is Operator.

C#:
foreach (Control c in Controls)
{
    if (c is Button)
    {
        c.BackColor = Color.FromArgb(255, 204, 0);
    }
}

Diese Variante hat außerdem noch den Vorteil, dass du nicht noch einen verwaisten Button im Speicher rumfliegen hast.
Da der Button innerhalb einer Schleife angelegt worden ist, wird dieser sowieso nach jedem Schleifendurchlauf freigegeben.
 
Zuletzt bearbeitet von einem Moderator:
Die foreach-Schleife hat ein paar Nachteile, deren du dir bewusst sein solltest:
  • Wenn ein Button in einem anderen Control sitzt, zum Beispiel einem Panel, dann findet die foreach-Schleife den Button nicht. Du müsstest also eine rekursive Schleife verwenden, die nicht nur über die Controls-Eigenschaft der Form iteriert, sondern auch über jede Controls-Eigenschaft von jedem gefundenen Control. Wenn deine Form viele Steuerelemente verwendet, dann ist so eine rekursive Schleife mit großer CPU-Last verbunden!
  • Wenn du mehrere Forms verwendest und sich die Farbe der Buttons auch auf diesen anderen Forms ändern soll, dann musst du zuerst über alle Forms iterieren und in jeder Form über alle Controls iterieren.
Ich weiß nicht wie groß dein Projekt ist. Bei einem kleinen Projekt (mit nur einer Form) sind die genannten Punkte wohl vernachlässigbar. In einem großen Projekt würden sie mich stören.

Ich schlage dir daher hier eine Alternative vor: du erstellst eine neue Klasse, ich habe sie mal ganz einfallsreich "MyButton" genannt. Diese erbt von Button und du gibst ihr eine statische Eigenschaft (oder Methode, wie es dir besser gefällt), über die du die Farbe aller instanziierten MyButtons ändern kannst. Das funktioniert über ein privates statisches Event, das ausgelöst wird, wenn sich die Farbe aller MyButtons ändern soll. Jeder MyButton abonniert dieses Event und ändert im EventHandler seine Farbe. Hier der Code:
C#:
using System;

namespace DeinProgrammName
{
    /// <summary>
    /// Entspricht einem herkömmlichen Button mit dem einzigen Unterschied, dass
    /// die BackColor-Eigenschaft nicht mehr im Designer angezeigt wird und
    /// dass eine neue statische Eigenschaft eingeführt wurde, welche die
    /// Hintergrundfarbe für ALLE MyButtons festlegt.
    /// </summary>
    internal class MyButton : System.Windows.Forms.Button
    {
        private static event EventHandler GlobalBackColorChanged;        
        private static System.Drawing.Color _GlobalBackColor = System.Drawing.Color.Blue;

        /// <summary>
        /// Statische Eigenschaft, die die Hintergrundfarbe für alle MyButtons festlegt.
        /// </summary>
        public static System.Drawing.Color GlobalBackColor
        {
            get { return MyButton._GlobalBackColor; }
            set
            {
                // Wenn die neue Hintergrundfarbe unterschiedlich zur Vorhergehenden ist...
                if (value != MyButton._GlobalBackColor)
                {
                    // ... dann neue Farbe verwenden
                    MyButton._GlobalBackColor = value;
                    // Und alle MyButtons informieren, dass die globale Hintergrundfarbe geändert wurde
                    GlobalBackColorChanged.Invoke(null, new EventArgs());
                }
            }
        }

        public MyButton()
        {
            // Globale Hintergrundfarbe verwenden
            this.BackColor = MyButton._GlobalBackColor;
            // GlobalBackColorChanged-Event abonnieren
            GlobalBackColorChanged += new EventHandler(MyButton_GlobalBackColorChanged);
        }

        private void MyButton_GlobalBackColorChanged(object sender, EventArgs e)
        {
            // Globale Hintergrundfarbe wurde geändert; jetzt neue Farbe verwenden
            this.BackColor = GlobalBackColor;
        }

        protected override void Dispose(bool disposing)
        {
            // Event-Abonnement löschen
            GlobalBackColorChanged -= new EventHandler(MyButton_GlobalBackColorChanged);
            // Basis-Dispose-Methode aufrufen
            base.Dispose(disposing);
        }

        // BackColor-Eigenschaft der Basisklasse überschreiben, damit ihr neue Attribute hinzugefügt werden können.
        [System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),
        System.ComponentModel.Browsable(false)]
        public override System.Drawing.Color BackColor
        {
            get
            {
                return base.BackColor;
            }
            set
            {
                base.BackColor = value;
            }
        }
    }
}
Füge diese Klasse in dein Projekt ein und kompiliere es. Daraufhin sollte der MyButton in Steuerelemente-ToolBox des Forms-Designer auftauchen. Du kannst diesen MyButton jetzt ganz bequem per Drag&Drop auf die Form ziehen.

In deinem Projekt bereits existierende Buttons müsstest du allerdings durch die MyButton-Klasse ersetzen. Das ist aber auch nicht weiter schwierig: dazu öffnest du die Designer-Dateien jeder Form (also wenn du eine "Form1" hast, dann Datei "Form1.Designer.cs" öffnen). Ganz unten findest du Einträge der Form
C#:
private System.Windows.Forms.Button button1;
für jeden Button. Hier änderst du das "System.Windows.Forms.Button" durch "DeinProgrammName.MyButton".

Ach ja, ändern kannst du die Farbe letztendlich mit folgender Codezeile:
C#:
MyButton.GlobalBackColor = System.Drawing.Color.Red;
 
Zuletzt bearbeitet:
Code:
<Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Pink"/>
        </Style>
</Window.Resources>
>
 
Zuletzt bearbeitet:
Zurück