Pengikatan WPF dengan StringFormat tidak berfungsi di ToolTips


87

Kode berikut memiliki pengikatan sederhana yang mengikat Teks dari TextBlock bernama MyTextBlock ke TextBox's Text dan properti ToolTip menggunakan notasi Binding yang sama persis:

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

Pengikatan juga menggunakan properti StringFormat yang diperkenalkan dengan .NET 3.5 SP1 yang berfungsi dengan baik untuk properti Teks di atas tetapi tampaknya rusak untuk ToolTip. Hasil yang diharapkan adalah "Ini adalah: Foo Bar" tetapi saat Anda mengarahkan kursor ke TextBox, ToolTip hanya menampilkan nilai pengikatan, bukan nilai yang diformat string. Ada ide?


3
Saya tidak bisa mendapatkan salah satu dari solusi yang disarankan di bawah ini untuk berfungsi, tetapi yang ini berhasil: stackoverflow.com/questions/4498649/…
17 dari 26

Jawaban:


156

ToolTips di WPF dapat berisi apa saja, bukan hanya teks, jadi toolTips menyediakan properti ContentStringFormat untuk saat Anda hanya menginginkan teks. Anda harus menggunakan sintaks yang diperluas sejauh yang saya tahu:

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

Saya tidak 100% yakin tentang validitas pengikatan menggunakan sintaks ElementName dari properti bersarang seperti itu, tetapi properti ContentStringFormat adalah yang Anda cari.


1
Begitu, saya pikir ToolTip hanyalah string biasa seperti di Windows Forms. Dan ya, sintaks ElementName dalam hal ini tidak dapat mengakses elemen luar.
huseyint

9
Perhatikan bahwa {} diperlukan hanya saat Anda menempatkan {0} di awal string, jadi Anda membutuhkannya untuk membedakan dari markup xaml lainnya.
Shimmy Weitzhandler

5
Pikiran = meledak. Aku baru saja memukul ini dan berkata "waaaat?"

2
Itu benar-benar menguatkan saya bahwa format string tidak 'hanya berfungsi' ketika tidak ada konverter yang ditentukan. Saya harus menulis stringformatConverter saya sendiri. MS menjatuhkan bola lagi ...
Gusdor

3
StringFormathanya akan diterapkan jika TargetTypetipe stringnya. ToolTipKonten adalah tipe object.
Johannes Wanzek

22

Ini bisa jadi bug. Saat Anda menggunakan sintaks pendek untuk tooltip:

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

StringFormat diabaikan tetapi ketika Anda menggunakan sintaks yang diperluas:

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

Ini bekerja seperti yang diharapkan.


Jawaban paling akurat .. Terima kasih!
Amir Mahdi Nassiri

5

Seperti yang dikatakan Matt, ToolTip dapat berisi apa pun di dalamnya sehingga Anda dapat mengikat TextBox.Text di dalam ToolTip Anda.

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

Bahkan Anda dapat Menumpuk kotak di dalam ToolTip dan mengatur tata letak teks Anda jika Anda mau.


3

Kode Anda bisa sesingkat ini:

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

Kami akan menggunakan fakta bahwa Converters tidak pernah diabaikan, tidak seperti StringFormat.

Masukkan ini ke dalam 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();
        }
    }
}

Masukkan ini ke ResourceDictionary.xaml Anda :

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

Meskipun saya lebih suka jawaban teratas, masalah ElementBinding membuat saya tersandung. Jawaban ini berhasil untuk kasus saya di mana yang lain tidak.
Reginald Blue

0

Dalam situasi ini, Anda dapat menggunakan pengikatan relatif:

<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

Berikut ini adalah solusi bertele-tele tetapi berhasil.

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

Saya lebih suka sintaks yang lebih sederhana, seperti yang ada di pertanyaan awal saya.


1
@Shimmy: "lebih baik" ada di mata yang melihatnya, dan tidak masalah untuk menandai pertanyaan Anda sendiri sebagai jawaban yang diterima
Andomar

1
@Shimmy Lebih buruk lagi, jawabannya termasuk lelucon '42'.

6
@Andomar, lebih baik apa yang orang putuskan dengan suara mereka, juga khususnya di sini, jawabannya hampir sama. membuat ppl menjawab pertanyaan Anda kemudian menyalin jawaban mereka dan mendapatkan reputasi karena itu adalah sikap yang sepenuhnya salah.
Shimmy Weitzhandler
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.