C# 如何防止WPF按钮在单击后保持高亮显示?

C# 如何防止WPF按钮在单击后保持高亮显示?,c#,.net,wpf,button,focus,C#,.net,Wpf,Button,Focus,单击标准WPF按钮时,它将以蓝色高亮显示(可能使用Windows主题设置中的蓝色),并且在与任何其他控件交互之前,它将保持高亮显示。对于我的应用程序,它让用户感到困惑 有没有一种简单的方法可以关闭这个按钮并使其恢复正常的样式? 我正在使用.NET 4。请尝试设置为false。该按钮将可单击,但不会保持焦点。这是Aero按钮具有焦点时的默认外观。您可以设置Focusable=“False”或使用自定义样式,该样式在按钮具有焦点时不会以不同方式呈现。比如: xmlns:theme=“clr命名空间:

单击标准WPF按钮时,它将以蓝色高亮显示(可能使用Windows主题设置中的蓝色),并且在与任何其他控件交互之前,它将保持高亮显示。对于我的应用程序,它让用户感到困惑

有没有一种简单的方法可以关闭这个按钮并使其恢复正常的样式?
我正在使用.NET 4。

请尝试设置为false。该按钮将可单击,但不会保持焦点。

这是Aero按钮具有焦点时的默认外观。您可以设置
Focusable=“False”
或使用自定义样式,该样式在按钮具有焦点时不会以不同方式呈现。比如:

xmlns:theme=“clr命名空间:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero”


您需要添加对PresentationFramework.Aero.dll的引用

所发生的是,按钮在被单击后接受输入焦点,就像您单击其他控件时所做的一样

Windows指示控件具有输入焦点(至少在Aero主题下)的方式是使用一个微妙的蓝色高亮显示

特别是对于按钮控件,当它具有输入焦点时,只需按Enter键即可“按下”该按钮。这就是为什么保持高光非常重要的原因,这样用户就知道会发生什么

更好的解决方案是在用户单击按钮后立即将焦点设置为窗口中的其他控件。这样,当用户按下Enter键时,它将不再自动突出显示,也不会自动触发任何操作。(这是你试图解决的真正的可用性问题,即使你还不知道。没有什么比用户在实际尝试键入内容时无意中点击按钮更令人困惑的了。)


您可以通过将其设置为false来防止按钮完全获得焦点,但我强烈建议不要这样做。完成此操作后,用户将无法仅使用键盘“按下”按钮。设计良好的应用程序应该始终能够被不喜欢或无法使用鼠标的用户访问。

这只是聚焦状态。要关闭它,您必须更改聚焦状态。这是最简单的使用混合


我不建议将Focusable设置为false,因为它会干扰键盘的使用

我需要做类似的事情,但在运行时的代码中,它看起来是这样的

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

它给了我想要的模板,然后删除渲染部分很容易。

我找到了两步解决方案。这个解决方案有点滑稽,但很有效。 我的推荐职位是

必须导入一个DLL,因为WPF不直接支持鼠标光标移动

  • 将System.Runtime.InteropServices添加到命名空间
  • 在主窗口或任何窗口代码中添加两行
  • [DllImport(“User32.dll”)]
    私有静态外部bool SetCursorPos(intx,inty)

  • 将这两行添加到单击事件中。
    SetCursorPos(0,0);
    ButtonName.FocusVisualStyle=null
  • 它适合我。

    
    
    <Style x:Key="TouchButton" TargetType="{x:Type Button}">
            <Setter Property="IsTabStop" Value="false"/>
            <Setter Property="Focusable" Value="false"/>
            <Setter Property="ClickMode" Value="Press"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="Border" CornerRadius="2" BorderThickness="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
                            <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Button.IsMouseOver" Value="True">
                                <Setter TargetName="Border" Property="Background" Value="Red"></Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    这会干扰用户仅使用键盘与应用程序交互的能力。一个设计拙劣的应用程序的特点是不使用鼠标就无法访问。@CodyGray,除非它显示在商店的触摸屏上。在这种情况下,焦点绝对是不需要的,键盘或鼠标输入根本不重要。@CodyGray或每个操作都有明确指定的键盘快捷键,如果空格键是其中之一,则更是如此。您应该注意,更改样式只会更改按钮具有焦点时的绘制方式。它不会改变按钮具有焦点的事实。这很重要,因为聚焦按钮是“特殊的”。它将按下Enter键解释为“单击”按钮,如果用户一眼就看不出哪个控件具有焦点,则可能会导致意外操作。因此,不建议仅仅改变样式。谢谢你。样式解决方案可能非常有用,但我担心我的用户会抱怨“Cody Gray”提到的问题最好是更改样式,以便可以看到焦点,但外观与突出显示的外观不同。例如,“轮廓”边框,但不是高亮显示的颜色。这就解决了科迪提出的问题。谢谢你的详细解释。我认为将焦点设置为隐藏控制或其他方式将是一个不错的选择。可能是另一个高度和宽度为零的按钮,因为我不希望这个按钮占用任何空间。可见性=无不应工作,因为焦点不能设置为未绘制的对象。还有一种方法我不必为点击事件中的每个按钮设置焦点吗?我的应用程序中的按钮太多。它们中的许多只有命令绑定。。没有事件。。MVVM@学习者:或用户最有可能与之交互的控件。我不知道你的窗口是如何布置的,但除非它包含的唯一东西是一个按钮,否则对于一个控件来说,可能有一个更自然的选择,那就是将焦点置于屏幕之外,而不是隐藏在屏幕之外。@learner:嗯,如果你真的发现自己不在
    <Style x:Key="TouchButton" TargetType="{x:Type Button}">
            <Setter Property="IsTabStop" Value="false"/>
            <Setter Property="Focusable" Value="false"/>
            <Setter Property="ClickMode" Value="Press"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="Border" CornerRadius="2" BorderThickness="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
                            <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Button.IsMouseOver" Value="True">
                                <Setter TargetName="Border" Property="Background" Value="Red"></Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>