Entwickler-Ecke

WinForms - Layout eines Buttons komplett deaktivieren u. Image anzeigen


Delete - Mi 11.08.10 11:20
Titel: Layout eines Buttons komplett deaktivieren u. Image anzeigen
Ich habe einen Button auf einer Form. Diesem ist eine ImageList zugewiesen, welche die verschiedenen Stadien (Normal, Hover, Click, etc.) repräsentiert. Jetzt möchte ich allerdings den nativen STil des Buttons komplett deaktivieren, damit unter dem Image herum der Std.-Button nicht angezeigt wird.


Ralf Jansen - Mi 11.08.10 11:38

Wenn du das Buttonverhalten nicht willst wieso nimmst du dann einen Button? Wenn du nur was anklickbares brauchst das kann jedes Control. Ist kein Monopol von Buttons und ich vermute wenn du das visuelle Verhalten komplett nicht willst ist Button zu benutzen eine Sackgasse.

Wenn es dir nur um den Border geht. FlatStyle = Flat setzen und FlatAppearance.Bordersize = 0.


Delete - Mi 11.08.10 11:52

Ich möchte für einen Button auch eine Button-Control verwenden. Denn das logische Verhalten eines Buttons macht ihn zum Button. Eine Grafik kann ich z. B. bei einer Form nur schlecht als CancelButton zuweisen. Ich möchte nicht, dass mein Button wie ein Std.Button aussieht, denn ich möchte gern eine eigene Grafik für meine GUI entwickeln.


Ralf Jansen - Mi 11.08.10 12:45

Dann hilft vermutlich nur einen eigenen Button abzuleiten und dann das zeichnen in OnPaint selbst zu erledigen.
Beispiel


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
public class MyButton : Button
    {
        protected override void OnPaint(PaintEventArgs e)
        {
            // Transparenz vortäuschen
            ButtonRenderer.DrawParentBackground(e.Graphics, e.ClipRectangle, this); 

            // um zur Designzeit einen Rahmen zu haben
            if (this.DesignMode)
            {
                using (Pen pen = new Pen(Color.Black))
                {
                        Rectangle rectangle = this.ClientRectangle;
                        rectangle.Height -= 1;
                        rectangle.Width -= 1;
                        pen.DashStyle = DashStyle.Dash;
                        e.Graphics.DrawRectangle(pen, rectangle);
                }
            }

            // Image aus Imagelist zentriert anzeigen 
            if (ImageList != null)
            {
                int imageIndex = Focused ? 0 : 1;
                this.ImageList.Draw(e.Graphics, new Point((Width - ImageList.ImageSize.Width) / 2, (Height - ImageList.ImageSize.Height) / 2), imageIndex);
            }
        }
    }


Geht vermutlich schon in die Richtung die du brauchst. Müsstest nur noch deine gewünschten Zustände des Buttons ermitteln um darüber den passenden imageIndex für ImageList.Draw zu bestimmen. Und natürlich ein wenig Fehlerhandling ;)


Delete - Mi 11.08.10 13:10

Danke für Deine Hilfe. Ich bin mal gespannt, was Dein Quelltext an neuen Infos hergibt.

Ich habe mich noch ein wenig durch das Web gegraben und folgende Lösung gefunden ...

Nun muss nur noch der Fokus-Rahmen beseitigt werden. http://stackoverflow.com/questions/148729/how-to-set-change-remove-focus-style-on-a-button-in-c
Ich habe es noch ein wenig abgewandelt, um das zur Entwurfszeit einstellen zu können.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
namespace MyDotNet.Windows.Forms
{
    public class Button : System.Windows.Forms.Button
    {
        public Button()
            : base()
        {
        }

        #region ShowFocusCues
        protected System.Boolean showFocusCues;

        protected override bool ShowFocusCues
        {
            get
            {
                return this.showFocusCues;
            }
        }
        #endregion

        #region FocusCues
        public virtual System.Boolean FocusCues
        {
            get
            {
                return this.showFocusCues;
            }
            set
            {
                this.showFocusCues = value;
            }
        }
        #endregion
    }
}

In den Quelltexten zur Form die entsprechenden Buttons von dieser Klasse ableiten. Jetzt gibt es in den Eigenschaften der IDE eine Eigenschaft FocusCues die bestimmt, ob der Fokus-Rahmen gezeichnet wird oder nicht.

@Ralf: Wie Du schon gechrieben hast müssen auch hier die verschiedenen Zustände ermittelt und die entsprechenden Images geladen werden.

Edit:

Eigenschaften ergänzt.