Подтвердить что ты не робот

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

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

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

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

Любые предложения?: -)

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

То, как я решил это, - установить 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; } }
}

Ответ 3

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

Райан

Ответ 6

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

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

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

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

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

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

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

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

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

Ответ 10

Если у вас есть текстовое поле и кнопка затем в текстовом событии текстового поля напишите button1.focus();

Он будет работать.

Ответ 11

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

Ответ 12

Мне повезло, просто установив для свойства Focusable кнопку false:

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