web-dev-qa-db-ja.com

StringFormatを使用したWPFバインディングがツールヒントで機能しない

次のコードには、MyTextBlockという名前のTextBlockのTextを、まったく同じBinding表記を使用してTextBoxのTextおよびToolTipプロパティにバインドする単純なバインディングがあります。

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox    Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}"
             ToolTip="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}" />
</StackPanel>

バインディングは、.NET 3.5 SP1で導入された StringFormatプロパティも使用します 上記のTextプロパティでは正常に機能していますが、ToolTipでは壊れているようです。期待される結果は「It is:Foo Bar」ですが、TextBoxの上にマウスを移動すると、ツールヒントにバインド値のみが表示され、文字列形式の値は表示されません。何か案は?

81
huseyint

WPFのツールヒントには、テキストだけでなく任意のものを含めることができるため、テキストが必要な時間にContentStringFormatプロパティを提供します。私の知る限り、拡張構文を使用する必要があります。

<TextBox ...>
  <TextBox.ToolTip>
    <ToolTip 
      Content="{Binding ElementName=myTextBlock,Path=Text}"
      ContentStringFormat="{}It is: {0}"
      />
  </TextBox.ToolTip>
</TextBox>

そのようなネストされたプロパティからElementName構文を使用したバインディングの有効性については100%確信が持てませんが、ContentStringFormatプロパティが探しています。

149
Matt Hamilton

バグかもしれません。ツールチップに短い構文を使用する場合:

<TextBox ToolTip="{Binding WhatEverYouWant StringFormat='It is: \{0\}'}" />

StringFormatは無視されますが、拡張構文を使用する場合:

<TextBox Text="text">
   <TextBox.ToolTip>
      <TextBlock Text="{Binding WhatEverYouWant StringFormat='It is: \{0\}'}"/>
   </TextBox.ToolTip>
</TextBox>

期待どおりに動作します。

21
MuiBienCarlota

Mattが言ったように、ToolTipは内部に何でも含めることができるので、ToolTip内でTextBox.Textをバインドできます。

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}">
        <TextBox.ToolTip>
            <TextBlock>
                <TextBlock.Text>
                    <Binding ElementName=MyTextBlock Path="Text" StringFormat="It is: {0}" />
                </TextBlock.Text>
            </TextBlock>
        </TextBox.ToolTip>
    </TextBox>
</StackPanel>

必要に応じて、ツールチップ内にグリッドをスタックし、テキストをレイアウトすることもできます。

4
Lucas Locatelli

コードは次のように短くすることができます。

<TextBlock ToolTip="{Binding PrideLands.YearsTillSimbaReturns,
    Converter={StaticResource convStringFormat},
    ConverterParameter='Rejoice! Just {0} years left!'}" Text="Hakuna Matata"/>

StringFormatとは異なり、コンバーターは無視されないという事実を使用します。

これをStringFormatConverter.csに入れます:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace TLKiaWOL
{
    [ValueConversion (typeof(object), typeof(string))]
    public class StringFormatConverter : IValueConverter
    {
        public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (ReferenceEquals(value, DependencyProperty.UnsetValue))
                return DependencyProperty.UnsetValue;
            return string.Format(culture, (string)parameter, value);
        }

        public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

これをResourceDictionary.xamlに入れます:

<conv:StringFormatConverter x:Key="convStringFormat"/>
3
Athari

この状況では、相対バインディングを使用できます。

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}"
             ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" />
</StackPanel>