128

ラベルのツールチップがあり、ユーザーがマウスを別のコントロールに移動するまで、ラベルを開いたままにしておきたいです。

ツールチップで次のプロパティを試しました。

StaysOpen="True"

ToolTipService.ShowDuration = "60000"

ただし、どちらの場合も、ツールチップは正確に5秒間しか表示されません。

これらの値が無視されるのはなぜですか?

4

10 に答える 10

213

これを1つのツールチップだけに設定する場合は、次のように、ツールチップを持つオブジェクトの期間を設定します。

<Label ToolTipService.ShowDuration="12000" Name="lblShowTooltip" Content="Shows tooltip">
    <Label.ToolTip>
        <ToolTip>
            <TextBlock>Hello world!</TextBlock>
        </ToolTip>
    </Label.ToolTip>
</Label>

この設計が選択されたのは、異なるコントロールで異なるタイムアウトを使用して同じツールチップを使用できるためだと思います。

アプリ全体でこれをグローバルに使用する場合は、承認された回答を参照してください。

于 2009-07-20T08:56:39.417 に答える
123

このコードを初期化セクションに入れるだけです。

ToolTipService.ShowDurationProperty.OverrideMetadata(
    typeof(DependencyObject), new FrameworkPropertyMetadata(Int32.MaxValue));
于 2011-11-29T09:13:19.430 に答える
17

これも今夜私を夢中にさせていました。ToolTipこの問題を処理するためにサブクラスを作成しました。私にとって、.NET 4.0では、ToolTip.StaysOpenプロパティは「実際に」開いたままではありません。

以下のクラスでは、propertyToolTipEx.IsReallyOpenの代わりにnewpropertyを使用しますToolTip.IsOpen。あなたはあなたが望むコントロールを手に入れるでしょう。呼び出しを介してDebug.Print()、デバッガーの出力ウィンドウで何回this.IsOpen = false呼び出されたかを確認できます。そんなにStaysOpen、または私は言うべき"StaysOpen"ですか?楽しみ。

public class ToolTipEx : ToolTip
{
    static ToolTipEx()
    {
        IsReallyOpenProperty =
            DependencyProperty.Register(
                "IsReallyOpen",
                typeof(bool),
                typeof(ToolTipEx),
                new FrameworkPropertyMetadata(
                    defaultValue: false,
                    flags: FrameworkPropertyMetadataOptions.None,
                    propertyChangedCallback: StaticOnIsReallyOpenedChanged));
    }

    public static readonly DependencyProperty IsReallyOpenProperty;

    protected static void StaticOnIsReallyOpenedChanged(
        DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        ToolTipEx self = (ToolTipEx)o;
        self.OnIsReallyOpenedChanged((bool)e.OldValue, (bool)e.NewValue);
    }

    protected void OnIsReallyOpenedChanged(bool oldValue, bool newValue)
    {
        this.IsOpen = newValue;
    }

    public bool IsReallyOpen
    {
        get
        {
            bool b = (bool)this.GetValue(IsReallyOpenProperty);
            return b;
        }
        set { this.SetValue(IsReallyOpenProperty, value); }
    }

    protected override void OnClosed(RoutedEventArgs e)
    {
        System.Diagnostics.Debug.Print(String.Format(
            "OnClosed: IsReallyOpen: {0}, StaysOpen: {1}", this.IsReallyOpen, this.StaysOpen));
        if (this.IsReallyOpen && this.StaysOpen)
        {
            e.Handled = true;
            // We cannot set this.IsOpen directly here.  Instead, send an event asynchronously.
            // DispatcherPriority.Send is the highest priority possible.
            Dispatcher.CurrentDispatcher.BeginInvoke(
                (Action)(() => this.IsOpen = true),
                DispatcherPriority.Send);
        }
        else
        {
            base.OnClosed(e);
        }
    }
}

小さな暴言:DependencyPropertyサブクラスの変更を受け入れる/拒否する/調整できるように、Microsoftがプロパティ(ゲッター/セッター)を仮想化しないのはなぜですか?またはvirtual OnXYZPropertyChanged、すべてのために作成しDependencyPropertyますか?うーん。

- -編集 - -

上記の私の解決策は、XAMLエディターでは奇妙に見えます-ツールチップは常に表示され、Visual Studioの一部のテキストをブロックします!

この問題を解決するためのより良い方法は次のとおりです。

一部のXAML:

<!-- Need to add this at top of your XAML file:
     xmlns:System="clr-namespace:System;assembly=mscorlib"
-->
<ToolTip StaysOpen="True" Placement="Bottom" HorizontalOffset="10"
        ToolTipService.InitialShowDelay="0" ToolTipService.BetweenShowDelay="0"
        ToolTipService.ShowDuration="{x:Static Member=System:Int32.MaxValue}"
>This is my tooltip text.</ToolTip>

いくつかのコード:

// Alternatively, you can attach an event listener to FrameworkElement.Loaded
public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    // Be gentle here: If someone creates a (future) subclass or changes your control template,
    // you might not have tooltip anymore.
    ToolTip toolTip = this.ToolTip as ToolTip;
    if (null != toolTip)
    {
        // If I don't set this explicitly, placement is strange.
        toolTip.PlacementTarget = this;
        toolTip.Closed += new RoutedEventHandler(OnToolTipClosed);
    }
}

protected void OnToolTipClosed(object sender, RoutedEventArgs e)
{
    // You may want to add additional focus-related tests here.
    if (this.IsKeyboardFocusWithin)
    {
        // We cannot set this.IsOpen directly here.  Instead, send an event asynchronously.
        // DispatcherPriority.Send is the highest priority possible.
        Dispatcher.CurrentDispatcher.BeginInvoke(
            (Action)delegate
                {
                    // Again: Be gentle when using this.ToolTip.
                    ToolTip toolTip = this.ToolTip as ToolTip;
                    if (null != toolTip)
                    {
                        toolTip.IsOpen = true;
                    }
                },
            DispatcherPriority.Send);
    }
}

ToolTip結論:クラスと。について何かが異なりますContextMenu。どちらにも、のような「サービス」クラスがToolTipServiceありContextMenuService、特定のプロパティを管理し、Popup表示中に「秘密の」親コントロールとして使用します。最後に、Web上のすべてのXAMLToolTipの例がクラスToolTipを直接使用していないことに気付きました。代わりに、sを埋め込んでいStackPanelますTextBlock。あなたに言わせること:「うーん...」

于 2012-10-19T18:23:16.900 に答える
8

ツールチップは、事前定義されたUI標準の方法でポップアップを使用していると想定しているため、ツールチップの代わりにポップアップを使用することをお勧めします。

StaysOpenが機能しない理由はわかりませんが、ShowDurationはMSDNに記載されているように機能します。これは、ツールチップが表示されたときに表示される時間です。違いを確認するには、少量(たとえば、500ミリ秒)に設定します。

あなたの場合の秘訣は「最後のホバーコントロール」状態を維持することですが、それができたら、1つのポップアップを使用している場合は、配置ターゲットとコンテンツを動的に(手動またはバインディングを介して)変更するのはかなり簡単です。または、複数を使用している場合は、最後に表示されたポップアップを非表示にします。

ウィンドウのサイズ変更と移動(ポップアップはコンテナと一緒に移動しない)に関しては、ポップアップに関するいくつかの落とし穴があります。そのため、動作を微調整する際にも、このことを念頭に置いておくとよいでしょう。詳細については、このリンクを参照してください。

HTH。

于 2009-05-22T08:06:31.317 に答える
7

の特定の要素のみWindowが実質的に無期限ToolTipの期間を持つように指定する場合は、それらの要素に対してを定義できStyleます。これはそのようなものを持ってWindow.ResourcesいるStyleためのものです:ButtonToolTip

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    ...>
    ...
    <Window.Resources>
        <Style x:Key="ButtonToolTipIndefinate" TargetType="{x:Type Button}">
            <Setter Property="ToolTipService.ShowDuration"
                    Value="{x:Static Member=sys:Int32.MaxValue}"/>
        </Style>
        ...
    </Window.Resources>
    ...
    <Button Style="{DynamicResource ButtonToolTipIndefinate}"
            ToolTip="This should stay open"/>
    <Button ToolTip="This Should disappear after the default time.">
    ...

に追加Style.Resourcesして、表示Styleされる外観を変更することもできToolTipます。次に例を示します。

<Style x:Key="ButtonToolTipTransparentIndefinate" TargetType="{x:Type Button}">
    <Style.Resources>
        <Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="HasDropShadow" Value="False"/>
        </Style>
    </Style.Resources>
    <Setter Property="ToolTipService.ShowDuration"
            Value="{x:Static Member=sys:Int32.MaxValue}"/>
</Style>

注:これを行ったときは、で使用BasedOnしたStyleので、通常のカスタムコントロールのバージョンに対して定義された他のすべてToolTipが適用されます。

于 2015-05-02T10:15:39.210 に答える
6

先日だけWPFツールチップと格闘していました。それ自体が現れたり消えたりするのを止めることはできないように思われるので、結局私はOpenedイベントを処理することにしました。たとえば、コンテンツが含まれていない限り、イベントが開かないようにしたかったので、Openedイベントを処理してから、次のようにしました。

tooltip.IsOpen = (tooltip.Content != null);

それはハックですが、うまくいきました。

おそらく、同様にClosedイベントを処理して、再度開くように指示して、イベントを表示したままにすることができます。

于 2009-05-22T06:41:45.620 に答える
3

完全を期すために:コードでは次のようになります。

ToolTipService.SetShowDuration(element, 60000);
于 2014-07-16T07:33:46.313 に答える
0

また、ツールチップに他のコントロールを配置したい場合は、ツールチップ自体がフォーカスを取得できるため、フォーカスできません。だからミカタンが言ったように、あなたのベストショットはポップアップです。

于 2009-05-22T15:57:14.687 に答える
0

同じコードで問題を修正しました。

ToolTipService.ShowDurationProperty.OverrideMetadata(typeof(DependencyObject)、new FrameworkPropertyMetadata(Int32.MaxValue));

于 2018-04-03T06:46:32.720 に答える
-4
ToolTipService.ShowDurationProperty.OverrideMetadata(
    typeof(DependencyObject), new FrameworkPropertyMetadata(Int32.MaxValue));

それは私のために働いています。この行をクラスコンストラクターにコピーします。

于 2012-04-02T11:10:52.750 に答える