Die WPF-Bindung mit StringFormat funktioniert in QuickInfos nicht


86

Der folgende Code verfügt über eine einfache Bindung, die den Text des TextBlocks mit dem Namen MyTextBlock unter Verwendung der exakt gleichen Bindungsnotation an die Text- und ToolTip-Eigenschaft von TextBox bindet:

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

Die Bindung verwendet auch die mit .NET 3.5 SP1 eingeführte StringFormat-Eigenschaft, die für die obige Text-Eigenschaft einwandfrei funktioniert, für die QuickInfo jedoch fehlerhaft zu sein scheint. Das erwartete Ergebnis ist "Es ist: Foo-Leiste". Wenn Sie jedoch mit der Maus über die Textbox fahren, zeigt die QuickInfo nur den Bindungswert an, nicht den mit Zeichenfolgen formatierten Wert. Irgendwelche Ideen?


3
Ich war nicht in der Lage, eine der unten vorgeschlagenen Lösungen zum Laufen
17 vom 26.

Antworten:


155

QuickInfos in WPF können alles enthalten, nicht nur Text. Sie bieten daher eine ContentStringFormat-Eigenschaft für die Zeiten, in denen Sie nur Text möchten. Soweit ich weiß, müssen Sie die erweiterte Syntax verwenden:

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

Ich bin mir nicht 100% sicher, ob die Bindung mithilfe der ElementName-Syntax einer solchen verschachtelten Eigenschaft gültig ist, aber die ContentStringFormat-Eigenschaft ist genau das, wonach Sie suchen.


1
Ich sehe, ich dachte, ToolTip ist nur eine einfache Zeichenfolge wie in Windows Forms. Und ja, die ElementName-Syntax kann in diesem Fall nicht auf das äußere Element zugreifen.
Huseyint

9
Beachten Sie, dass das {} nur erforderlich ist, wenn Sie das {0} am Anfang der Zeichenfolge platzieren, damit Sie es von den anderen xaml-Markups unterscheiden können.
Shimmy Weitzhandler

5
Geist = geblasen. Ich habe das gerade getroffen und war wie "waaaat?"

2
Es hat mich wirklich verärgert, dass das String-Format nicht einfach funktioniert, wenn kein Konverter angegeben ist. Ich musste meinen eigenen stringformatConverter schreiben. MS lässt den Ball wieder fallen ...
Gusdor

3
StringFormatwird nur angewendet, wenn der TargetTypeTyp is string ist. ToolTipDer Inhalt ist vom Typ object.
Johannes Wanzek

22

Es könnte ein Fehler sein. Wenn Sie eine kurze Syntax für den Tooltip verwenden:

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

StringFormat wird ignoriert, aber wenn Sie eine erweiterte Syntax verwenden:

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

Es funktioniert wie erwartet.


Die genaueste Antwort .. Danke!
Amir Mahdi Nassiri

Das hat super geklappt. Mein Problem gelöst. Vielen Dank.
Miyamoto Musashi

5

Wie Matt sagte, kann ToolTip alles enthalten, sodass Sie eine TextBox.Text in Ihre ToolTip einbinden können.

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

Sie können sogar ein Raster in die QuickInfo stapeln und Ihren Text gestalten, wenn Sie möchten.


3

Ihr Code kann so kurz sein:

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

Wir werden die Tatsache verwenden, dass Konverter im Gegensatz zu StringFormat niemals ignoriert werden.

Fügen Sie dies in StringFormatConverter.cs ein :

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

Fügen Sie dies in Ihre ResourceDictionary.xaml ein :

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

Obwohl ich die Top-Antwort vorgezogen hätte, hat mich das ElementBinding-Problem gestolpert. Diese Antwort funktionierte für meinen Fall, in dem die anderen dies nicht taten.
Reginald Blue

0

In dieser Situation können Sie die relative Bindung verwenden:

<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

Das Folgende ist eine wortreiche Lösung, aber sie funktioniert.

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

Ich würde eine viel einfachere Syntax bevorzugen, so etwas wie die in meiner ursprünglichen Frage.


1
@ Shimmy: "besser" liegt im Auge des Betrachters, und es ist in Ordnung, Ihre eigene Frage als akzeptierte Antwort zu markieren
Andomar

1
@Shimmy Noch schlimmer, seine Antwort enthält einen '42'-Witz.

6
@Andomar, besser ist, was die Leute mit ihren Stimmen entscheiden, auch hier besonders, es ist fast genau die gleiche Antwort. Es ist eine völlig falsche Einstellung, ppl dazu zu bringen, Ihre Fragen zu beantworten, dann ihre Antworten zu kopieren und sich einen Ruf dafür zu verschaffen.
Shimmy Weitzhandler

4
@ Shimmy: Ich glaube nicht, dass Sie den Ruf erlangen, Ihre eigene Antwort als akzeptiert zu
markieren
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.