2008-09-29 7 views
18

Ich habe ein paar Tasten, von denen ich modifiziert habe, wie sie aussehen. Ich habe sie als flache Buttons mit einem Hintergrund und einem benutzerdefinierten Rahmen eingestellt, so dass sie alle hübsch aussehen und nichts mehr wie normale Buttons (eigentlich sehen sie jetzt wie Office 2003 Buttons aus ;-). Die Schaltflächen haben eine Grenze von einem Pixel.Wie setze/ändere/entferne ich den Fokus-Stil auf einer Schaltfläche in C#?

Wenn die Schaltfläche ausgewählt wird (erhält den Fokus entweder durch einen Klick oder eine Tastaturaktion wie das Drücken der Tabulatortaste), wird die Schaltfläche plötzlich um eine zusätzliche Farbe mit derselben Grenze erweitert. Außerdem, wenn ich die Grenze für einen Pixel deaktiviere, erhält die Schaltfläche keinen Fokus von einem Pixel.

Im Netz diese Frage viel wie gefragt wird: ‚Wie kann ich Fokus auf einer Schaltfläche deaktivieren‘, aber das ist nicht das, was ich will: sollte der Fokus existiert noch, nur nicht Anzeige in der Art und Weise tut es jetzt.

Irgendwelche Vorschläge? :-)

Antwort

0

Sicher können Sie den Knopf selbst zeichnen. Eine der Staatsflaggen ist fokussiert.

Also auf das Zeichenereignis, wenn das Flag fokussiert ist, gehen Sie voran und zeichnen Sie die Schaltfläche, wie Sie möchten, andernfalls übergeben Sie es einfach an die Basismethode.

+0

Könnten Sie ein wenig mehr ausarbeiten, da es kein Draw * -Ereignis * gibt? Es gibt jedoch ein Paint-Ereignis, aber keine Statusflags. =) Ich verstehe und mag die Idee, nur ein bisschen auf die tatsächliche Umsetzung verloren. –

0

Erwägen Sie, Ihren eigenen Zeichencode für die Schaltfläche zu implementieren. Auf diese Weise haben Sie die volle Kontrolle. In der Vergangenheit habe ich ein eigenes Control-Derivat implementiert, das meine Schaltfläche individuell anpast und alle Button-Eigenschaften für meine Zwecke implementiert, aber Sie sollten in der Lage sein, das Malen der Schaltfläche zu überschreiben und selbst zu steuern, um zu steuern, wie es in jedem Zustand gezeichnet wird , einschließlich wenn fokussiert.

30

Ist das der Effekt, nach dem Sie suchen?

public class NoFocusCueButton : Button 
{ 
    protected override bool ShowFocusCues 
    { 
     get 
     { 
      return false; 
     } 
    } 
} 

können Sie diese benutzerdefinierten Schaltfläche Klasse verwenden wie eine normale Taste, aber es wird kein zusätzliches Rechteck Fokus geben.

+2

Danke für den tollen Vorschlag! Dies beseitigt ein inneres gräuliches Fokusrechteck, aber nicht den hinzugefügten einen Pixelrand (was es insgesamt zu zwei Pixelrändern macht). –

+2

@Chris Jester-Young: Überprüfen Sie die Antwort von Josh Stribling, um die zusätzliche Ein-Pixel-Grenze auszublenden. – Marc

1

Der zweite Rahmen, der hinzugefügt wird, ist der Windows-Standardrahmen "Standardschaltfläche". Sie haben vielleicht bemerkt, dass, wenn Sie die meisten Dialogfelder mit mehreren Schaltflächen durchblättern (wie etwa ein Fenster mit den Eigenschaften der Systemsteuerung), der ursprüngliche "doppelseitige" Button "normal" wird und der fokussierte Button "doppelt umrandet" wird. "

Dies ist nicht unbedingt Fokus bei der Arbeit, sondern eher eine visuelle Anzeige der Aktion durch Drücken der Enter-Taste.

Es klingt für mich, als ob Sie sich nicht wirklich für dieses interne Arbeiten interessieren. Sie möchten, dass das Display keine zwei Ränder hat - völlig verständlich. Die interne Arbeit soll erklären, warum Sie dieses Verhalten sehen. Jetzt ... Um es zu reparieren.

Das erste, was ich versuchen würde - und bedenken Sie, ich habe dies nicht bestätigt - ist ein Hack. Wenn eine Schaltfläche den Fokus erhält (dadurch wird der doppelte Rahmen erhalten), deaktivieren Sie den einzelnen Rahmen. Sie können den gewünschten Effekt erzielen, und das ist ziemlich einfach. (Hook in das Focus-Ereignis. Noch besser, Unterklasse Button und Override OnFocus, dann verwenden Sie diese Unterklasse für Ihre zukünftigen Schaltflächen.)

Allerdings könnte das neue, peinliche visuelle Nebenwirkungen einführen. In diesem Sinne - und weil Hacks selten die beste Antwort sind - muss ich "offiziell" empfehlen, was andere gesagt haben: Custom paint the button. Auch wenn der Code hier vielleicht übertrieben ist, erläutert diese link at CodeProject, wie man das macht (VB-Link; Sie müssen übersetzen). Sie sollten in einem vollständig benutzerdefinierten Modus in der Lage sein, diese zweite Grenze vollständig zu entfernen.

2

Es gibt einen anderen Weg, der gut für flache Tasten funktioniert. Verwenden Sie keine Tasten, sondern Etiketten. Da Sie die Benutzeroberfläche für die Schaltfläche vollständig ersetzen, spielt es keine Rolle, ob Sie ein Schaltflächensteuerelement oder ein Label verwenden. Behandeln Sie den Klick auf die gleiche Weise.

Das funktionierte für mich, obwohl es keine gute Übung ist, es ist ein guter Hack und solange Sie den Knopf natürlich nennen (und die Quelle kommentieren), werden andere Programmierer die Idee aufgreifen.

Ryan

0

Stellen Sie die FocusVisualStyle Abhängigkeitseigenschaft auf null in Ihrem Stil und die gestrichelte Grenze verschwunden sein.

Von MSDN: Styling for Focus in Controls, and FocusVisualStyle

Windows Presentation Foundation (WPF) bietet zwei parallele Mechanismen zur das visuelle Erscheinungsbild eines Steuerung zu ändern, wenn es Tastatur Fokus erhält. Der erste Mechanismus ist die Verwendung von Eigenschaften-Settern für Eigenschaften wie als IsKeyboardFocused innerhalb des Styles oder Vorlage, die auf das Steuerelement angewendet wird. T Der zweite Mechanismus besteht darin, einen separaten Stil als Wert der FocusVisualStyle-Eigenschaft bereitzustellen; der „Fokus visuelle Stil“ erzeugt eine separate visuelle Struktur für ein adorner , die auf der Steuer zieht, eher als die visuelle Struktur ändert der Steuerung oder anderen UI-Elements durch ihn zu ersetzen. In diesem Thema werden die Szenarien erörtert, in denen jeder dieser -Mechanismen geeignet ist.

Die zusätzliche Grenze Sie durch den Focusvisualstyle und nicht in der Steuervorlage definiert sehen ist, so dass Sie den Stil zu löschen oder zu überschreiben, die die Grenze zu entfernen.

+0

Dies ist für WPF, nicht für Winforms. – DMan

6

Eine andere Option (obwohl ein wenig hacktastic) ist, einen Event-Handler an das GotFocus-Ereignis der Schaltfläche anzuhängen. Übergeben Sie in diesem Ereignishandler den Wert False an die Methode der Schaltfläche. Also, zum Beispiel:

void myButton_GotFocus(object sender, EventArgs e) 
{ 
    myButton.NotifyDefault(false); 
} 

Ich nehme an, dass dies jedes Mal funktioniert, aber ich habe es nicht ausgiebig getestet. Es funktioniert jetzt für mich, damit bin ich zufrieden.

0

Wenn Sie eine Textbox und einen Knopf dann auf Textchange Ereignis von Textbox schreiben button1.focus();

Es wird funktionieren.

14

Erstellen Sie eine benutzerdefinierte Schaltfläche:

public partial class CustomButton: Button 
{ 
    public ButtonPageButton() 
    { 
     InitializeComponent(); 

     this.SetStyle(ControlStyles.Selectable, false); 
    } 
} 

Das loswerden, dass lästige Grenze bekommen!;-)

+0

Das funktionierte für mich und war einfach. – theJerm

+0

Leider deaktiviert dies die Fähigkeit, den Knopf zu fokussieren. Das Überschreiben von 'ShowFocusCues' scheint besser zu sein. –

-3

Ich habe nur viel Glück hat die Fokussierbare Eigenschaft der Schaltfläche Einstellung falsch sein:

<Button HorizontalAlignment="Left" Margin="0,2" 
     Command="{Binding OpenSuspendedJobCommand, Mode=OneWay}" 
     Focusable="False" 
     Style="{StaticResource ActionButton}" Content="Open Job..." /> 
+1

WPF ist nicht dasselbe wie WinForms. – Neolisk

19

ich das gleiche Problem mit der störenden Doppel Grenze hatte, und über diesen Thread gestolpert suchen eine Antwort ...

So wie ich dieses Problem gelöst war, die BorderSize-0 setzen dann OnPaint in meine eigene Grenze ziehen

* Hinweis: Nicht die gesamte Taste, nur die Grenze

Ein einfaches Beispiel wäre:

public class CustomButton : Button 
{ 
    public CustomButton() 
     : base() 
    { 
     // Prevent the button from drawing its own border 
     FlatAppearance.BorderSize = 0; 
     FlatStyle = System.Windows.Forms.FlatStyle.Flat; 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     // Draw Border using color specified in Flat Appearance 
     Pen pen = new Pen(FlatAppearance.BorderColor, 1); 
     Rectangle rectangle = new Rectangle(0, 0, Size.Width - 1, Size.Height - 1); 
     e.Graphics.DrawRectangle(pen, rectangle); 
    } 
} 

In meinem Fall ist dies, wie ich einen Knopf gemacht, die einen Toolstripbutton imitiert, wo die Grenze ist nur sichtbar, wenn Sie über die Schaltfläche schweben:

public class ToolButton : Button 
{ 
    private bool ShowBorder { get; set; } 

    public ToolButton() 
     : base() 
    { 
     // Prevent the button from drawing its own border 
     FlatAppearance.BorderSize = 0; 

     // Set up a blue border and back colors for the button 
     FlatAppearance.BorderColor = Color.FromArgb(51, 153, 255); 
     FlatAppearance.CheckedBackColor = Color.FromArgb(153, 204, 255); 
     FlatAppearance.MouseDownBackColor = Color.FromArgb(153, 204, 255); 
     FlatAppearance.MouseOverBackColor = Color.FromArgb(194, 224, 255); 
     FlatStyle = System.Windows.Forms.FlatStyle.Flat; 

     // Set the size for the button to be the same as a ToolStripButton 
     Size = new System.Drawing.Size(23, 22); 
    } 

    protected override void OnMouseEnter(EventArgs e) 
    { 
     base.OnMouseEnter(e); 

     // Show the border when you hover over the button 
     ShowBorder = true; 
    } 

    protected override void OnMouseLeave(EventArgs e) 
    { 
     base.OnMouseLeave(e); 

     // Hide the border when you leave the button 
     ShowBorder = false; 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     // The DesignMode check here causes the border to always draw in the Designer 
     // This makes it easier to place your button 
     if (DesignMode || ShowBorder) 
     { 
      Pen pen = new Pen(FlatAppearance.BorderColor, 1); 
      Rectangle rectangle = new Rectangle(0, 0, Size.Width - 1, Size.Height - 1); 
      e.Graphics.DrawRectangle(pen, rectangle); 
     } 
    } 



    // Prevent Text from being set on the button (since it will be an icon) 
    [Browsable(false)] 
    public override string Text { get { return ""; } set { base.Text = ""; } } 

    [Browsable(false)] 
    public override ContentAlignment TextAlign { get { return base.TextAlign; } set { base.TextAlign = value; } } 
} 
0

Sie auch eine unsichtbare Schaltfläche erstellen und es aktiv, wenn Sie eine andere Taste drücken machen.