2

現在、バッキング ビュー モデルのプロパティにIsOpena のプロパティをバインドしようとしています。ToolTipさらに、バインディング モードは「OneWayToSource」に設定されます。

これは にStyle適用され、次の定義TreeViewItemを含むです。ToolTip

<Style TargetType="TreeViewItem">
    <Setter Property="ToolTip">
        <Setter.Value>
            <ToolTip IsOpen="{Binding IsToolTipOpen, Mode=OneWayToSource}">
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Name}"/>
                    <TextBlock Text="{Binding CurrentValue, StringFormat={}Value: {0}}"/>
                    <TextBlock Text="{Binding UnitName, StringFormat={}Unit: {0}}"
                               Visibility="{Binding HasUnit, Converter={StaticResource BooleanToVisibilityConverter}}"/>
                </StackPanel>
            </ToolTip>
        </Setter.Value>
    </Setter>
</Style>

バインド先のプロパティのコードは次のとおりです。

public bool IsToolTipOpen
{
    get
    {
       return mIsToolTipOpen;
    }
    set
    {
        PegasusContext.Current.LogMessage( new PegasusMessage( string.Format( "IsTooltipOpen: {0}", value ), LogLevel.Debug ) );

        if( mIsToolTipOpen == value ) return;
        mIsToolTipOpen = value;

        if( mIsToolTipOpen )
        {
            BackingIO.BeginWatching();
        }
        else
        {
            BackingIO.StopWatching();
        }
    }
}

ToolTip が初めてIsToolTipOpen開かれると、その値を に設定するプロパティが呼び出されfalseます。さらに、ToolTip が閉じると、値が ... に再度設定されIsToolTipOpenますfalse。それ以降は毎回、期待どおりに値が設定されます。最初の ToolTip を開いた後、ToolTip が添付された他の項目で奇妙な動作を実行します。たとえば、IsToolTipOpenプロパティをに設定してから、すぐにtrue元に戻します。false繰り返しますが、その後開くたびに、ToolTip正常に動作します。

これは、私のIsToolTipOpenプロパティ set メソッドの最初の行にあるロギング コードからのレポートです (いくつかのコメントを手書きで追加しています)。

TreeViewItem A:
IsTooltipOpen: False <-- ToolTip Opened
IsTooltipOpen: False <-- ToolTip Closed
IsTooltipOpen: True  <-- ToolTip Opened
IsTooltipOpen: False <-- ToolTip Closed

TreeViewItem B:
IsTooltipOpen: True <-- ToolTip Open
IsTooltipOpen: False <-- ToolTip Open, occured at the same time as the previous entry.
IsTooltipOpen: False <-- ToolTip Closed
IsTooltipOpen: True <-- ToolTip Opened
IsTooltipOpen: False <-- ToolTip Closed

それで、何が起こっているのか誰かが知っているかどうか興味がありましたか?そして可能な解決策は?

4

2 に答える 2

1

これは私を混乱させ、何が起こっているのかを理解するために、しばらくそれを突っ込んでしまいました。完全な理解に達したかどうかは完全にはわかりませんが、開始したときよりも進んでいます = D

ToolTipで非常に単純な動作を複製しGridました。イベントと をよく見て、ToolTipServiceどこにも行きませんでした。その後、WPF Snoop (所属なし) を使用して、アプリケーションが最初に起動さDataContextれたときに を調べました。ToolTip

一見、 にはToolTipがありませんDataContext。初めて開けた瞬間。 コンテキストなし

ToolTipを継承しDataContextます。 環境

したがって、私が想定しているのは (これは私がぼんやりしている場所です)、最初に の上にマウスを置いたときToolTipDataContextがまだ正しくバインドされていないため、get/set が正しく起動できないということです。メッセージがまったく表示されない理由は、OneWayToSourceここで説明されているバインディング モードの動作の結果です: OneWayToSource バインディングが .NET 4.0 で壊れているようです。バインディングを選択した場合、最初のラウンドでは がまったく開かないTwoWayことに気付くでしょうが、 のレイト バインディングの後は正しく機能します。ToolTipDataContext

がこれを行う理由はToolTip、実装方法の結果であり、その共有ToolTipsが発生する可能性があります。ビジュアル ツリー内には存在しません

ツールチップ (およびその中のすべて) は、ビジュアル ツリーの一部ではありません。画像との親子関係ではなく、プロパティと値の関係にあります。

ツールチップが実際に表示されると、WPF は継承可能なプロパティの値を配置ターゲットからツールチップに伝達する特別な作業を行います。

もっともらしく聞こえると思いますが、実際に何かできることはありますか?

一部の人々はToolTip、ビジュアル ツリー上のものに をバインドしたいと考えており、親オブジェクトを見つけるのが困難なため、いくつかの回避策が生まれました (解決策を探しているときに、これらに出会いました: http://blogs.msdn. com/b/tom_mathews/archive/2006/11/06/binding-a-tooltip-in-xaml.aspx ユーザー コントロールでツールチップを取得して、データバインドされたテキストを表示し、開いたままにする

両方とも、「ToolTip が開いたときに配置される UIElement を相対的に取得または設定する」のきちんとしたプロパティToolTipに依存しています。MSDN .PlacementTarget

要約すると、IsOpenプロパティをバインドして正しく動作させるために、モックアップでこれを行いました。

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}" Background="#FF95CAFF" 
    >
<Grid>
    <TextBlock Text="{Binding Path=TestObject.Name}">
        <TextBlock.ToolTip>
            <ToolTip IsOpen="{Binding DataContext.TestObject.IsToolTipOpen}" 
                DataContext="{Binding Path=PlacementTarget,
                    RelativeSource={RelativeSource Self}}" >
                <StackPanel Orientation="Vertical">
                    <!-- Show me what the `DataContext` is -->
                    <TextBlock Text="{Binding Path=DataContext}" />
                </StackPanel>
            </ToolTip>
        </TextBlock.ToolTip>
    </TextBlock>
</Grid>

プログラムのロード時にコンテキストが見つかりました。 ハッピーコンテキスト

この場合、DataContextWpfApplication1.MainWindowであり、テストに使用している というプロパティにバインドしていますTestObject。テンプレートで必要な `DataContext アイテムを見つけるには、おそらく構文を少しいじる必要があります (構造によっては、既に行った方法で行う方が簡単な場合があります)。

大幅に間違っていることを言っている場合は、お知らせください。

于 2013-11-10T13:43:03.633 に答える