web-dev-qa-db-ja.com

C#でボタンのフォーカススタイルを設定/変更/削除するにはどうすればよいですか?

いくつかのボタンがあり、その外観を変更しました。私はそれらを背景とカスタムの境界線を持つフラットボタンとして設定しました。これにより、それらはすべてき​​れいになり、通常のボタンのようには見えなくなりました(実際には、Office 2003のボタンのように見えます;-)。ボタンには1ピクセルの境界があります。

ただし、ボタンが選択されると(クリック、またはタブキーを押すなどのキーボードアクションによってフォーカスが取得されると)、ボタンは突然同じ色の境界線を取得し、2ピクセルの境界線になります。さらに、1ピクセルの境界線を無効にすると、ボタンのフォーカスが1ピクセルの境界線になりません。

ネットでは、この質問は「ボタンのフォーカスを無効にするにはどうすればよいですか?」のようによく尋ねられますが、それは私が望んでいることではありません。フォーカスはまだ既存であり、displayではありません=現在の方法で。

助言がありますか? :-)

24
pbean

これはあなたが探している効果ですか?

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

通常のボタンと同じようにこのカスタムボタンクラスを使用できますが、フォーカスがある四角形が追加されることはありません。

38
Michael L Perry

私は迷惑な二重の境界線と同じ問題を抱えていて、答えを探してこのスレッドに出くわしました...

私がこれを解決した方法は、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; } }
}
21
Josh Stribling

カスタムボタンを作成します。

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

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

それはその迷惑な境界線を取り除くでしょう! ;-)

15
Marcus Rex

もう1つのオプション(少しハッカスティックですが)は、ボタンのGotFocusイベントにイベントハンドラーをアタッチすることです。そのイベントハンドラーで、ボタンのNotifyDefault()メソッドにFalseの値を渡します。したがって、たとえば:

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

私はこれが毎回うまくいくと思います、しかし私はそれを広範囲にテストしていません。今のところ問題なく機能しているので、満足しています。

6
Blake

フラットスタイルのボタンでうまく機能する別の方法があります。ボタンではなくラベルを使用します。ボタンのUIを完全に置き換えるので、ボタンコントロールとラベルのどちらを使用しても問題ありません。同じ方法でクリックを処理します。

これは私にとってはうまくいきましたが、良い習慣ではありませんが、これは良いハックであり、ボタンに明らかに名前を付け(そしてソースにコメントを付ける)限り、他のコーダーはそのアイデアを理解します。

ライアン

2
Ryan O'Neill

追加される2番目の境界線は、Windows標準の「デフォルトボタン」境界線です。複数のボタン(コントロールパネルのプロパティウィンドウなど)を持つほとんどのダイアログボックスをタブで移動すると、元の「二重枠」ボタンが「通常」になり、フォーカスされているボタンが「二重枠」になります。 」

これは必ずしも仕事に集中する必要はありませんが、Enterキーを押すことによって行われたアクションの視覚的な表示です。

私には、あなたはその内部の働きについてあまり気にしていないように思えます。ディスプレイに2つの境界線がないようにしたい-完全に理解できる。内部の作業は、この動作が見られる理由を説明することです。今...それを試して修正する。

私が最初に試そうとしていること、そしてこれを検証していないことを念頭に置いて、ハックです。ボタンがフォーカスを受け取ると(それによって二重の境界線が表示されます)、単一の境界線をオフにします。あなたはあなたが望む効果を得るかもしれません、そしてそれはかなり簡単です。 (Focusイベントにフックします。さらに良いことに、Buttonをサブクラス化し、OnFocusをオーバーライドしてから、そのサブクラスを将来のボタンに使用します。)

ただし、それにより、新しくて厄介な視覚的副作用が生じる可能性があります。つまり、ハッキングが最善の答えになることはめったにないので、私は他の人が言ったことを「公式に」推奨する必要があります。カスタムペイントボタンです。ここのコードはやり過ぎかもしれませんが、これ CodeProjectのリンク はその方法を説明しています(VBリンク。翻訳が必要です)。フルオンのカスタムモードでは、その2番目の境界線を完全に取り除くことができる必要があります。

1
John Rudy

非表示のボタンを作成して、別のボタンを押すたびにアクティブにすることもできます。

0

テキストボックスとボタンがある場合、テキストボックスのtextchangeイベントでbutton1.focus();と書き込みます

それが動作します。

0
Amit

確かに自分でボタンを描くことができます。状態フラグの1つがフォーカスされています。

したがって、描画イベントで、フラグがフォーカスされている場合は、先に進んでボタンを好きなように描画します。それ以外の場合は、単にベースメソッドに渡します。

0
Orion Adrian

ボタンに独自の描画コードを実装することを検討してください。そうすれば、完全に制御できます。以前は、ボタンをカスタムペイントし、目的に合わせてすべてのボタン特性を実装する独自のControl派生物を実装しましたが、ボタンの描画をオーバーライドして自分で実行できるため、すべての状態での描画方法を制御できます。 、焦点を合わせた場合を含む。

0
Jeff Yates

FocusVisualStyle 依存関係プロパティをスタイルでnullに設定すると、点線の枠がなくなります。

MSDNから: コントロールでのフォーカスのスタイリング、およびFocusVisualStyle

Windows Presentation Foundation(WPF)は、コントロールがキーボードフォーカスを受け取ったときにコントロールの外観を変更するための2つの並列メカニズムを提供します。最初のメカニズムは、コントロールに適用されるスタイルまたはテンプレート内のIsKeyboardFocusedなどのプロパティのプロパティセッターを使用することです。 T2番目のメカニズムは、FocusVisualStyleプロパティの値として別のスタイルを提供することです。 "フォーカスビジュアルスタイル"は、コントロールまたは他のUI要素のビジュアルツリーを置き換えることによって変更するのではなく、コントロールの上に描画する装飾用の個別のビジュアルツリーを作成します。このトピックでは、これらの各メカニズムが適切であるシナリオについて説明します。

表示されるextra borderはFocusVisualStyleで定義されており、コントロールテンプレートでは定義されていないため、スタイルを削除またはオーバーライドして、境界線を削除する必要があります。

0
Pop Catalin