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

Как я могу предотвратить выделение кнопок WPF после нажатия?

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

Ответ 3

Это поиск по умолчанию для кнопок 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

Ответ 4

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

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

Ответ 5

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

//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 было легко.