it-swarm.com.ru

Как установить/изменить/удалить стиль фокуса на кнопке в C #?

У меня есть пара кнопок, которые я изменил, как они выглядят. Я установил их в виде плоских кнопок с фоном и пользовательской рамкой, чтобы они выглядели красиво и больше не походили на обычные кнопки (на самом деле они теперь выглядят как кнопки Office 2003 ;-). Кнопки имеют границу в один пиксель.

Однако, когда кнопка выбрана (фокусировка осуществляется нажатием кнопки или действия клавиатуры, например нажатия клавиши табуляции), кнопка внезапно получает дополнительную рамку того же цвета, что делает ее двухпиксельной рамкой. Более того, когда я отключаю однопиксельную границу, кнопка не получает однопиксельную границу в фокусе.

В сети этот вопрос часто задают, например, «Как я могу отключить фокус на кнопке», но это не то, чего я хочу: фокус должен все еще существовать , просто не отображать так, как он это делает сейчас.

Какие-либо предложения? :-)

22
pbean

Это тот эффект, который вы ищете?

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

Вы можете использовать этот класс пользовательских кнопок, как обычную кнопку, но он не даст вам дополнительный прямоугольник в фокусе.

37
Michael L Perry

У меня была та же проблема с раздражающей двойной рамкой, и я наткнулся на эту тему в поисках ответа ...

Я решил это, установив BorderSize в 0, а затем нарисовал мою собственную границу в OnPaint

* Примечание: Не вся кнопка, только граница

Простой пример будет:

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);
    }
}

В моем случае, вот как я сделал кнопку, которая имитирует ToolStripButton, где граница видна только при наведении курсора на кнопку:

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; } }
}
21
Josh Stribling

Сделайте пользовательскую кнопку:

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

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

Это избавит от этой надоедливой границы! ;-)

14
Marcus Rex

Другой вариант (хотя и немного странный) - присоединить обработчик событий к событию GotFocus кнопки. В этом обработчике событий передайте значение False методу NotifyDefault() кнопки. Так, например:

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

Я предполагаю, что это будет работать каждый раз, но я не проверял это всесторонне. Пока это работает для меня, поэтому я доволен этим.

6
Blake

Есть другой способ, который хорошо работает для плоских кнопок. Не используйте кнопки, но надписи. Поскольку вы полностью заменяете пользовательский интерфейс кнопки, не имеет значения, используете ли вы элемент управления кнопкой или метку. Просто обработайте щелчок таким же образом.

Это сработало для меня, хотя это не очень хорошая практика, это хороший взлом, и, пока вы явно называете кнопку (и комментируете источник), другие кодировщики поймут эту идею.

Райан

2
Ryan O'Neill

Вторая добавляемая граница - это стандартная граница Windows «кнопка по умолчанию». Возможно, вы заметили, что при переходе по большинству диалоговых окон с несколькими кнопками (например, в любом окне свойств панели управления) исходная «двойная» кнопка становится «нормальной», а кнопка, находящаяся в фокусе, становится «двойной рамкой». "

Это не обязательно фокус на работе, а скорее визуальная индикация действия, предпринятого нажатием клавиши Enter. 

Для меня это звучит так, будто тебя не волнует эта внутренняя работа. Вы хотите, чтобы дисплей не имел двух границ - полностью понятно. Внутренняя работа состоит в том, чтобы объяснить, почему вы видите такое поведение. Теперь ... чтобы попытаться это исправить.

Первое, что я попробую - и имейте в виду, я не проверял это - это взломать. Когда кнопка получает фокус (получая двойную границу), отключите вашу единственную границу. Вы можете получить желаемый эффект, и это довольно просто. (Присоединитесь к событию Focus. Еще лучше, создайте подкласс Button и переопределите OnFocus, а затем используйте этот подкласс для своих будущих кнопок.)

Однако это может привести к появлению новых, неуклюжих визуальных побочных эффектов. В этом ключе - и поскольку хаки редко бывают лучшим ответом - я должен «официально» рекомендовать то, что сказали другие: Custom Paint the button. Хотя код здесь может быть излишним, эта ссылка в CodeProject обсуждает, как это сделать (ссылка на VB; вам нужно будет перевести). В полностью настраиваемом режиме вы должны полностью избавиться от этой второй границы.

1
John Rudy

Вы также можете создать невидимую кнопку и сделать ее активной при каждом нажатии другой кнопки.

0
Tim Kathete Stadler

Если у вас есть текстовое поле и кнопка , То при событии textchange текстового поля Напишите button1.focus();

Это будет работать.

0
Amit

Конечно, вы можете нарисовать кнопку самостоятельно. Один из государственных флагов сфокусирован.

Так что на событии рисования, если флаг сфокусирован, идите вперед и нарисуйте кнопку так, как вам нравится, в противном случае просто передайте ее базовому методу.

0
Orion Adrian

Подумайте о реализации собственного кода рисования для кнопки. Таким образом, у вас есть полный контроль. В прошлом я реализовывал свой собственный производный элемент управления, который настраивал рисование моей кнопки и реализовывал все характеристики кнопки для моих целей, но вы должны иметь возможность переопределить рисование кнопки и сделать это самостоятельно, таким образом контролируя, как она рисует в каждом состоянии. в том числе, когда сосредоточены.

0
Jeff Yates

Установите для свойства FocusVisualStyle dependency значение null в вашем стиле, и пунктирная граница исчезнет.

Из MSDN: Стилизация для фокуса в элементах управления и FocusVisualStyle

Windows Presentation Foundation (WPF) предоставляет два параллельных механизма для изменение внешнего вида контролировать, когда он получает клавиатуру фокус. Первый механизм заключается в использовании установщики свойств для таких свойств как IsKeyboardFocused в пределах стиля или шаблон, который применяется к контроль. TВторой механизм заключается в укажите отдельный стиль в качестве значения свойства FocusVisualStyle; метод «Фокус визуального стиля» создает отдельное визуальное дерево для рекламодателя который опирается на элемент управления, вместо изменения визуального дерева элемента управления или другого элемента пользовательского интерфейса заменить его. В этой теме обсуждается сценарии, где каждый из них механизмы уместны.

Дополнительная граница, которую вы видите, определяется FocusVisualStyle, а не в шаблоне элемента управления, поэтому вам нужно удалить или переопределить стиль, чтобы удалить границу.

0
Pop Catalin