StringFormat ile WPF bağlama, ToolTips üzerinde çalışmıyor


87

Aşağıdaki kod, aynı Binding gösterimini kullanarak MyTextBlock adlı TextBlock metnini TextBox'ın Text ve ToolTip özelliğine bağlayan basit bir bağlamaya sahiptir:

<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>

Bağlama ayrıca, .NET 3.5 SP1 ile tanıtılan StringFormat özelliğini kullanır; bu, yukarıdaki Metin özelliği için iyi çalışıyor ancak Araç İpucu için bozuk görünüyor. Beklenen sonuç "It is: Foo Bar" dır, ancak TextBox üzerine geldiğinizde, ToolTip dize formatlı değeri değil, yalnızca bağlama değerini gösterir. Herhangi bir fikir?


3
İşe aşağıda önerilen çözümlerden birini almak mümkün değildi, ama bu did: stackoverflow.com/questions/4498649/...
17 26

Yanıtlar:


156

WPF'deki Araç İpuçları yalnızca metin değil, her şeyi içerebilir, bu nedenle metin istediğiniz zamanlar için bir ContentStringFormat özelliği sağlarlar. Bildiğim kadarıyla genişletilmiş sözdizimini kullanmanız gerekecek:

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

Bunun gibi yuvalanmış bir özellikten ElementName sözdizimini kullanarak bağlamanın geçerliliğinden% 100 emin değilim, ancak aradığınız ContentStringFormat özelliği.


1
Görüyorum, ToolTip'in Windows Forms'daki gibi sadece düz bir dize olduğunu düşündüm. Ve evet, bu durumda ElementName sözdizimi dış elemana erişemez.
huseyint

9
{} Karakterinin yalnızca {0} karakterini dizenin başına yerleştirdiğinizde gerekli olduğunu ve bu nedenle diğer xaml işaretlerinden ayırt etmeniz gerektiğini unutmayın.
Shimmy Weitzhandler

5
Zihin = şişmiş. Sadece buna çarptım ve "waaaat?"

2
Stringformat'ın dönüştürücü belirtilmediğinde 'sadece çalışmaması' beni gerçekten güçlendirdi. Kendi stringformatConverter'ımı yazmam gerekiyordu. MS yine topu düşürüyor ...
Gusdor

3
StringFormatyalnızca TargetTypeis türü dizge olduğunda uygulanacaktır . ToolTipİçerik türündedir object.
Johannes Wanzek

22

Bu bir hata olabilir. Araç ipucu için kısa sözdizimi kullandığınızda:

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

StringFormat yok sayılır, ancak genişletilmiş sözdizimini kullandığınızda:

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

Beklendiği gibi çalışıyor.


En doğru cevap .. Teşekkürler!
Amir Mahdi Nassiri

5

Matt'in dediği gibi, Araç İpucu içinde herhangi bir şey içerebilir, böylece sizin için Araç İpucunuzun içine bir Metin Kutusu. Metni bağlayabilirsiniz.

<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>

Hatta Araç İpucunun içine bir ızgara yerleştirebilir ve isterseniz metninizi düzenleyebilirsiniz.


3

Kodunuz şu kadar kısa olabilir:

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

StringFormat'ın aksine Dönüştürücülerin asla göz ardı edilmediği gerçeğini kullanacağız.

Bunu StringFormatConverter.cs içine koyun :

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();
        }
    }
}

Bunu ResourceDictionary.xaml dosyanıza koyun :

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

En iyi cevabı tercih etsem de, ElementBinding sorunu beni tetikledi. Bu cevap, diğerlerinin yapmadığı benim durumum için çalıştı.
Reginald Blue

0

Bu durumda, göreli bağlamayı kullanabilirsiniz:

<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>

-7

Aşağıdaki çok uzun bir çözüm ama işe yarıyor.

<StackPanel>
  <TextBox Text="{Binding Path=., StringFormat='The answer is: {0}'}">
    <TextBox.DataContext>
      <sys:Int32>42</sys:Int32>
    </TextBox.DataContext>
    <TextBox.ToolTip>
      <ToolTip Content="{Binding}" ContentStringFormat="{}The answer is: {0}" />
    </TextBox.ToolTip>
  </TextBox>
</StackPanel>

Orijinal sorumdaki gibi çok daha basit bir sözdizimi tercih ederim.


1
@Shimmy: "daha iyi", bakanın gözündedir ve kendi sorunuzu kabul edilen cevap olarak işaretlemekte sorun yoktur
Andomar

1
@Shimmy Daha da kötüsü, cevabı bir '42' şakası içeriyor.

6
@Andomar, insanların oylarıyla karar vermesi daha iyi, burada da özel, neredeyse aynı cevap. ppl yapmak sorularınızı yanıtlamak, sonra onların yanıtlarını kopyalamak ve itibar kazanmak, çünkü tamamen yanlış bir tutumdur.
Shimmy Weitzhandler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.