8

ToolStripItemsは、それらの上にマウスを置くと、フォーカスされていないフォームであっても、アクティブな強調表示を表示します。ただし、フォームにフォーカスがない限り、ツールチップは表示されません。ToolStripの「クリックスルー」ハックを見たことがあります。親フォームにフォーカスがないときにToolStripButtonにツールチップを表示させる方法を知っている人はいますか?

ありがとう!

4

4 に答える 4

6

問題は、ToolStripButtonやToolStripDropDownButtonなどのToolStripの「コントロール」がControlから継承されないことです。今のところ、ユーザーがボタンにカーソルを合わせるたびにToolStripにフォーカスすることで、この問題に対処しました。ボタンのMouseHoverイベントの発生が遅すぎます。「showtooltip」コードが実行された後なので、ToolStripDropDownButtonクラスを拡張し、新しいボタンを使用しました。このメソッドは、ToolStripItemから継承する他のボタンのようなクラスのいずれでも機能するはずです。

public class ToolStripDropDownEx : ToolStripDropDownButton
{
    public ToolStripDropDownEx(string text)
    {
    }

    protected override void OnMouseHover(EventArgs e)
    {
        if (this.Parent != null)
            Parent.Focus();
        base.OnMouseHover(e);
    } 
}
于 2008-10-04T13:35:16.857 に答える
3

おそらく、このコードの 2 つのアプローチのうちの 1 つが、正しい方向への出発点となるでしょう...

public Form1()
{
    InitializeComponent();

    tooltip = new ToolTip();
    tooltip.ShowAlways = true;
}

private ToolTip tooltip;
private void toolStripButton_MouseHover(object sender, EventArgs e)
{
    if (!this.Focused)
    {
        ToolStripItem tsi = (ToolStripItem)sender;
        tooltip.SetToolTip(toolStrip1, tsi.AutoToolTip ? tsi.ToolTipText : tsi.Text);
        /*tooltip.Show(tsi.AutoToolTip ? tsi.ToolTipText : tsi.Text, this, 
            new Point(toolStrip1.Left, toolStrip1.Bottom));*/
    }
}

private void toolStripButton_MouseLeave(object sender, EventArgs e)
{
    tooltip.RemoveAll();
}

最初の問題は、ボタンに直接設定できないこと、Control から継承されないこと、ストリップ上ではあるがボタン上でない限りツールチップが表示されないことです。

2番目の問題(コメントアウトされた方法)は、まったく表示されないことです。理由はよくわかりませんが、デバッグできるかもしれません。

于 2008-09-28T08:29:14.637 に答える
2

私はいくつかのことを試しましたが、これが最も簡単であることがわかりました

toolstripbutton アイテムを作成するときに、ホバー イベントにイベント ハンドラーを追加しました。

private sub SomeCodeSnippet()

    Me.tooltipMain.ShowAlways = True

    Dim tsi As New ToolStripButton(String.Empty, myImage)
    tsi.ToolTipText = "my tool tip text"
    toolstripMain.Add(tsi)

    AddHandler tsi.MouseHover, AddressOf ToolStripItem_MouseHover

end sub

次に、イベント ハンドラー:

Private Sub ToolStripItem_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs)

    If TypeOf sender Is ToolStripButton Then
        Me.tooltipMain.SetToolTip(Me.toolstripMain, CType(sender, ToolStripButton).ToolTipText)
    End If

End Sub

これは非常にうまく機能しますが、最初にツールストリップにカーソルを合わせると、最初のわずかな遅延に気付きます

于 2012-01-19T21:07:13.283 に答える
1

私は同じことをやろうとしていたのですが、それはかなり難しく、やる価値がないと判断しました。その理由は、.NET コードは、ウィンドウがアクティブな場合にのみツールチップを表示するように内部的に特別に設計されているためです。Win32 レベルでこれをチェックしているため、コードを偽造するのは困難です。

"GetActiveWindow()" をチェックして false を返す ToolTip.cs のコード スニペットを次に示します。コード内に「ツールヒントはアクティブな Windows でのみ表示する必要があります」というコメントが表示されます。

ところで、Visual Studio 2008 を使用した .NET BCL のすべてのソース コードを確認できます。私が使用した手順は次のとおりです。

http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx

// refer VsWhidbey 498263: ToolTips should be shown only on active Windows.
private bool IsWindowActive(IWin32Window window)
{ 
    Control windowControl = window as Control;
    // We want to enter in the IF block only if ShowParams does not return SW_SHOWNOACTIVATE. 
    // for ToolStripDropDown ShowParams returns SW_SHOWNOACTIVATE, in which case we DONT want to check IsWindowActive and hence return true. 
    if ((windowControl.ShowParams & 0xF) != NativeMethods.SW_SHOWNOACTIVATE)
    { 
        IntPtr hWnd = UnsafeNativeMethods.GetActiveWindow();
        IntPtr rootHwnd =UnsafeNativeMethods.GetAncestor(new HandleRef(window, window.Handle), NativeMethods.GA_ROOT);
        if (hWnd != rootHwnd)
        { 
            TipInfo tt = (TipInfo)tools[windowControl];
            if (tt != null && (tt.TipType & TipInfo.Type.SemiAbsolute) != 0) 
            { 
                tools.Remove(windowControl);
                DestroyRegion(windowControl); 
            }
            return false;
        }
    } 
    return true;
} 
于 2008-11-20T23:26:07.440 に答える