web-dev-qa-db-ja.com

クリック後にWPFボタンが強調表示されたままになるのを防ぐにはどうすればよいですか?

標準のWPFボタンをクリックすると、青色で強調表示され(おそらくWindowsテーマが設定されている青色を使用)、他のコントロールを操作するまで強調表示されたままになります。私のアプリケーションでは、ユーザーにとって混乱を招きます。

これをオフにしてボタンを通常のスタイルに戻す簡単な方法はありますか? .NET 4を使用しています。

36
learner

起こるのは、ボタンをクリックした後、他のコントロールがするように、ボタンがクリックされた後、ボタンが入力フォーカスを受け入れることです。

また、Windowsが(少なくともAeroテーマの下で)コントロールに入力フォーカスがあることを示す方法は、微妙な青色の強調表示です。

特にボタンコントロールの場合、入力フォーカスがある場合は、単に Enter キーはそのボタンを「プッシュ」します。そのため、ハイライトを維持することが非常に重要であり、ユーザーが何を期待できるかを知ることができます。

より良い解決策は、ユーザーがボタンをクリックした直後に、ウィンドウ内の別のコントロールにフォーカスを設定することです。そうすることで、ユーザーがを押しても自動的に強調表示されなくなり、アクションが自動的にトリガーされなくなります Enter キー。 (これはreal解決しようとしているユーザビリティの問題です(まだ知らない場合でも)ボタンほど混乱するものはありませんユーザーが実際に何かを入力しようとしているときに、うっかりクリックされてしまいます。)

あなたはcouldFocusable property をfalseに設定することでボタンがフォーカスを取得するのを防ぎますが、私はこれに対して非常にお勧めします。これを実行すると、ユーザーがキーボードのみを使用してボタンを「押す」方法はなくなります。適切に設計されたアプリケーションは、alwaysで、マウスを使用したくない、または使用できないユーザーがアクセスできる必要があります。

49
Cody Gray

Focusable をfalseに設定してみてください。ボタンはクリック可能ですが、フォーカスは維持されません。

10
HCL

これは、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への参照を追加する必要があります

2
CodeNaked

それは単に焦点を合わせた状態です。オフにするには、フォーカス状態を変更する必要があります。 Blendを使用すると最も簡単です。

キーボードの使用を妨げるため、Focusableをfalseに設定することはお勧めしません

2
Erno de Weerd

同様のことをする必要がありましたが、実行時のコードでは、このように見えました

//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を使用することでしたが、すべてのデフォルトテンプレートを作成する必要がありました。 ;)
使用

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

それは私が欲しかったテンプレートを与え、そしてレンダリングセクションを削除するのは簡単でした。

0
Guish

私は2ステップの解決策を見つけました。解決策は少し面白いですが、動作しています。私の紹介記事は次のとおりです。

グローバルFocusVisualStyleをすべてのコントロールから削除する方法?

および C#WPF application .NET 4.5 Set Mouse Position

WPFはマウスカーソルの移動を直接サポートしていないため、1つDLLをインポートする必要があります。

  1. system.Runtime.InteropServicesを名前空間に追加します
  2. MainWindowまたはウィンドウのコードに2行追加します

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

  1. これら2行をクリックイベントに追加します。 SetCursorPos(0, 0); ButtonName.FocusVisualStyle = null;

わたしにはできる 。

0
Özgür KAYA