A vinculação WPF com StringFormat não funciona nas dicas de ferramentas


87

O código a seguir tem uma vinculação simples que vincula o Text do TextBlock denominado MyTextBlock à propriedade Text and ToolTip do TextBox usando exatamente a mesma notação Binding:

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

A associação também usa a propriedade StringFormat introduzida no .NET 3.5 SP1, que está funcionando bem para a propriedade Text acima, mas parece estar quebrada para a dica de ferramenta. O resultado esperado é "It is: Foo Bar", mas quando você passa o mouse sobre o TextBox, a dica de ferramenta mostra apenas o valor de ligação, não o valor formatado da string. Alguma ideia?


3
Não consegui fazer com que nenhuma das soluções sugeridas abaixo funcionasse, mas esta funcionou: stackoverflow.com/questions/4498649/…
17 de 26 de

Respostas:


156

As dicas de ferramentas no WPF podem conter qualquer coisa, não apenas texto, portanto, fornecem uma propriedade ContentStringFormat para os momentos em que você deseja apenas texto. Você precisará usar a sintaxe expandida, tanto quanto eu sei:

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

Não tenho 100% de certeza sobre a validade da vinculação usando a sintaxe ElementName de uma propriedade aninhada como essa, mas a propriedade ContentStringFormat é o que você está procurando.


1
Eu vejo, eu pensei que a dica de ferramenta é apenas uma string simples como no Windows Forms. E sim, a sintaxe ElementName, neste caso, não pode acessar o elemento externo.
huseyint

9
Observe que o {} é necessário apenas quando você coloca o {0} no início da string, portanto, você precisa dele para distinguir das outras marcações xaml.
Shimmy Weitzhandler

5
Mente = explodido. Eu acabei de bater nisso e disse "waaaat?"

2
Realmente me surpreendeu que o formato de string não 'simplesmente funciona' quando nenhum conversor é especificado. Eu tive que escrever meu próprio stringformatConverter. MS deixando a bola cair novamente ...
Gusdor 26/11/12

3
StringFormatsó será aplicado quando TargetTypefor o tipo de string. ToolTipO conteúdo é do tipo object.
Johannes Wanzek,

22

Pode ser um bug. Quando você usa uma sintaxe curta para a dica de ferramenta:

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

StringFormat é ignorado, mas quando você usa sintaxe expandida:

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

Funciona como esperado.


A resposta mais precisa .. Obrigado!
Amir Mahdi Nassiri

5

Como Matt disse, a dica de ferramenta pode conter qualquer coisa dentro, então para você você pode vincular um TextBox.Text dentro de sua dica de ferramenta.

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

Até você pode empilhar uma grade dentro da dica de ferramenta e fazer o layout de seu texto, se quiser.


3

Seu código pode ser tão curto quanto este:

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

Usaremos o fato de que Conversores nunca são ignorados, ao contrário de StringFormat.

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

Coloque isso em seu ResourceDictionary.xaml :

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

Embora eu preferisse a resposta principal, o problema do ElementBinding me enganou. Essa resposta funcionou para o meu caso, enquanto os outros não.
Reginald Blue

0

Nessa situação, você pode usar ligação relativa:

<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

O seguinte é uma solução prolixo, mas funciona.

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

Eu preferiria uma sintaxe muito mais simples, algo como o da minha pergunta original.


1
@Shimmy: "melhor" está nos olhos de quem vê, e não há problema em marcar sua própria pergunta como resposta aceita
Andomar

1
@Shimmy Pior ainda, sua resposta inclui uma piada de '42'.

6
@Andomar, melhor é o que o pessoal decide com os votos, principalmente aqui, é quase a mesma resposta. fazer o ppl responder às suas perguntas e depois copiar suas respostas e ganhar reputação por isso é uma atitude completamente errada.
Shimmy Weitzhandler
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.