Как предотвратить выделение кнопок WPF после нажатия? - PullRequest
36 голосов
/ 10 мая 2011

При нажатии стандартной кнопки WPF она выделяется синим цветом (возможно, с использованием синего цвета из любой установленной темы Windows) и остается выделенной, пока вы не будете взаимодействовать с любым другим элементом управления.Для моего приложения это сбивает с толку пользователя.

Есть ли простой способ отключить это и вернуть кнопку к ее нормальному стилю?Я использую .NET 4.

Ответы [ 6 ]

49 голосов
/ 10 мая 2011

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

И способ, которым Windows указывает, что у элемента управления есть фокус ввода (по крайней мере, в теме Aero), с тонкой синей подсветкой.

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

Лучшее решение - установить фокус на другой элемент управления в вашем окне сразу после того, как пользователь нажал на кнопку. Таким образом, он больше не будет автоматически подсвечиваться, и никакие действия не будут автоматически инициироваться, когда пользователь нажимает клавишу Enter . (Это - проблема реальной юзабилити, которую вы пытаетесь решить, даже если вы еще не знаете ее. Нет ничего более запутанным, чем случайное нажатие кнопки, когда пользователь на самом деле пытается что-то набрать .)

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

10 голосов
/ 10 мая 2011

Попробуйте установить для Focusable значение false. Кнопка будет активна, но не будет оставаться сфокусированной.

2 голосов
/ 10 мая 2011

Это просто сфокусированное состояние. Чтобы выключить его, вам нужно будет изменить состояние фокусировки. Проще всего использовать Blend.

Я не рекомендую устанавливать для Focusable значение false, поскольку это мешает работе с клавиатурой

2 голосов
/ 10 мая 2011

Это внешний вид кнопок Aero по умолчанию, когда они имеют фокус.Вы можете установить Focusable="False" или использовать собственный стиль, который не отображает его по-другому, когда кнопка имеет фокус.Примерно так:

xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
<Style x:Key="BaseButtonStyle" TargetType="{x:Type ButtonBase}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ButtonBase}">
                <theme:ButtonChrome Name="Chrome" Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
                        RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"
                        SnapsToDevicePixels="true">
                    <ContentPresenter Margin="{TemplateBinding Padding}"
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                </theme:ButtonChrome>
                <ControlTemplate.Triggers>
                    <!--
                    Do not show blue when focused
                    <Trigger Property="IsKeyboardFocused" Value="true">
                        <Setter TargetName="Chrome" Property="RenderDefaulted" Value="true" />
                    </Trigger>-->
                    <Trigger Property="ToggleButton.IsChecked" Value="true">
                        <Setter TargetName="Chrome" Property="RenderPressed" Value="true" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#ADADAD" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}" TargetType="{x:Type ToggleButton}" />
<Style x:Key="{x:Type RepeatButton}" BasedOn="{StaticResource BaseButtonStyle}" TargetType="{x:Type RepeatButton}" />
<Style x:Key="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}" TargetType="{x:Type Button}" />

Вам нужно добавить ссылку на PresentationFramework.Aero.dll

0 голосов
/ 19 марта 2019

Я нашел 2 шага решения.Решение немного смешное, но работает.Мои ссылочные посты:

Как удалить глобальный FocusVisualStyle для всех элементов управления?

и Приложение CF WPF .NET 4.5 Установить положение мыши

Одна DLL должна быть импортирована, поскольку WPF не поддерживает перемещение курсора мыши напрямую.

  1. добавляет System.Runtime.InteropServices в пространство имен
  2. Добавьте две строки в MainWindowили любой другой код вашего окна

[DllImport("User32.dll")] private static extern bool SetCursorPos(int X, int Y);

Добавьте эти 2 строки в событие клика.SetCursorPos(0, 0); ButtonName.FocusVisualStyle = null;

У меня работает.

0 голосов
/ 14 ноября 2012

Мне нужно было сделать что-то подобное, но в коде во время выполнения это выглядело так:

//You can get this XAML by using System.Windows.Markup.XamlWriter.Save(yourButton.Template)";
             const string controlXaml = "<ControlTemplate TargetType=\"ButtonBase\" " +
                                    "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" " +
                                    "xmlns:s=\"clr-namespace:System;assembly=mscorlib\" " +
                                    "xmlns:mwt=\"clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero\">" +
                                    "<mwt:ButtonChrome Background=\"{TemplateBinding Panel.Background}\" " +
                                    "BorderBrush=\"{TemplateBinding Border.BorderBrush}\" " +
                                    "RenderDefaulted=\"{TemplateBinding Button.IsDefaulted}\" " +
                                    //"RenderMouseOver=\"{TemplateBinding UIElement.IsMouseOver}\" " +
                                    "RenderPressed=\"{TemplateBinding ButtonBase.IsPressed}\" Name=\"Chrome\" SnapsToDevicePixels=\"True\">" +
                                    "<ContentPresenter RecognizesAccessKey=\"True\" " +
                                    "Content=\"{TemplateBinding ContentControl.Content}\" " +
                                    "ContentTemplate=\"{TemplateBinding ContentControl.ContentTemplate}\" " +
                                    "ContentStringFormat=\"{TemplateBinding ContentControl.ContentStringFormat}\" " +
                                    "Margin=\"{TemplateBinding Control.Padding}\" " +
                                    "HorizontalAlignment=\"{TemplateBinding Control.HorizontalContentAlignment}\" " +
                                    "VerticalAlignment=\"{TemplateBinding Control.VerticalContentAlignment}\" " +
                                    "SnapsToDevicePixels=\"{TemplateBinding UIElement.SnapsToDevicePixels}\" /></mwt:ButtonChrome>" +
                                    "<ControlTemplate.Triggers>" +
                                    "<Trigger Property=\"UIElement.IsKeyboardFocused\">" +
                                    "<Setter Property=\"mwt:ButtonChrome.RenderDefaulted\" TargetName=\"Chrome\"><Setter.Value><s:Boolean>True</s:Boolean></Setter.Value></Setter>" +
                                    "<Trigger.Value><s:Boolean>True</s:Boolean></Trigger.Value></Trigger>" +
                                    "<Trigger Property=\"ToggleButton.IsChecked\">" +
                                    "<Setter Property=\"mwt:ButtonChrome.RenderPressed\" TargetName=\"Chrome\"><Setter.Value><s:Boolean>True</s:Boolean></Setter.Value></Setter>" +
                                    "<Trigger.Value><s:Boolean>True</s:Boolean></Trigger.Value></Trigger>" +
                                    "<Trigger Property=\"UIElement.IsEnabled\"><Setter Property=\"TextElement.Foreground\"><Setter.Value><SolidColorBrush>#FFADADAD</SolidColorBrush></Setter.Value></Setter>" +
                                    "<Trigger.Value><s:Boolean>False</s:Boolean></Trigger.Value></Trigger></ControlTemplate.Triggers>" +
                                    "</ControlTemplate>";

        var xamlStream = new MemoryStream(System.Text.Encoding.Default.GetBytes(controlXaml));
        var _buttonControlTemplate = (ControlTemplate)System.Windows.Markup.XamlReader.Load(xamlStream);
        var yourButton = new Button() { Template = _buttonControlTemplate };

Вы можете видеть, что я комментирую строку "" RenderMouseOver "

Моя первая надеждаиспользовал FrameworkElementFactory, но мне нужно было создать все шаблоны по умолчанию .... ALL BY HAND!;)
Использование

System.Windows.Markup.XamlWriter.Save(myButton.Template)

Это дало мне шаблон, который я хотел, и затем удаление раздела Render было легко.

...