Связывание WPF с StringFormat не работает во всплывающих подсказках

Следующий код имеет простую привязку, которая связывает текст TextBlock с именем MyTextBlock со свойством TextBox и свойством 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>

Привязка также использует Свойство StringFormat, представленное в .NET 3.5 SP1, который отлично работает для указанного выше свойства Text, но, похоже, не работает для всплывающей подсказки. Ожидаемый результат - «Это: панель Foo», но при наведении курсора на TextBox всплывающая подсказка показывает только значение привязки, а не значение в строковом формате. Есть идеи?

Мне не удалось заставить работать ни одно из предложенных ниже решений, но это сработало: stackoverflow.com/questions/4498649/…

17 of 26 06.12.2012 19:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
88
1
30 310
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Всплывающие подсказки в WPF могут содержать что угодно, а не только текст, поэтому они предоставляют свойство ContentStringFormat для тех случаев, когда вам нужен только текст. Насколько я знаю, вам нужно будет использовать расширенный синтаксис:

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

Я не уверен на 100% в правильности привязки с использованием синтаксиса ElementName из такого вложенного свойства, но свойство ContentStringFormat - это то, что вы ищете.

Понятно, я думал, что всплывающая подсказка - это обычная строка, как в Windows Forms. И да, синтаксис ElementName в этом случае не может получить доступ к внешнему элементу.

huseyint 13.10.2008 16:13

Обратите внимание, что {} требуется только тогда, когда вы помещаете {0} в начало строки, поэтому вам нужно, чтобы он отличался от других разметок xaml.

Shimmy Weitzhandler 13.12.2009 02:34

Разум = взорван. Я просто нажал на это и подумал: «Уаааат?»

user1228 17.08.2010 21:48

Меня очень огорчило то, что строковый формат не «просто работает», когда не указан конвертер. Пришлось написать собственный конвертер строкового формата. МС снова бросает мяч ...

Gusdor 26.11.2012 20:41

Здесь нельзя использовать ни ElementName, ни RelativeSourceAncestorType), когда я пытался. Итак, как это вообще может быть связано с чем-то значимым?

O. R. Mapper 03.03.2014 13:35

Это решило мою проблему с форматированием содержимого кнопки. В других примерах, которые я нашел, просто используется StringFormat с Binding и ничего не упоминается о различиях между элементами управления содержимым и другими элементами управления.

Ondrej Janacek 01.07.2014 13:03

StringFormat будет применяться только в том случае, если TargetType является строковым типом. ToolTip Содержимое относится к типу object.

Johannes Wanzek 22.10.2014 15:29
Ответ принят как подходящий

Следующее решение является многословным, но оно работает.

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

Я бы предпочел гораздо более простой синтаксис, похожий на тот, что был в моем исходном вопросе.

@Shimmy: «лучше» в глазах смотрящего, и можно отметить свой вопрос принятым ответом

Andomar 13.12.2009 13:06

@Shimmy Хуже того, в его ответе есть шутка про 42.

user1228 17.08.2010 21:54

@Andomar, лучше люди решают своими голосами, особенно здесь, это почти тот же ответ. заставлять людей отвечать на ваши вопросы, а затем копировать их ответы и завоевывать репутацию, поскольку это совершенно неправильное отношение.

Shimmy Weitzhandler 17.08.2010 22:41

Ваш код может быть таким коротким:

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

Хотя я предпочел бы верхний ответ, проблема с ElementBinding меня сбила с толку. Этот ответ работал в моем случае, тогда как другие нет.

Reginald Blue 12.12.2018 20:16

Как сказал Мэтт, всплывающая подсказка может содержать что угодно внутри, поэтому для вас вы можете привязать 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>

Даже вы можете сложить сетку внутри всплывающей подсказки и расположить текст, если хотите.

Это могло быть ошибкой. Когда вы используете короткий синтаксис для всплывающей подсказки:

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

Работает как положено.

Самый точный ответ .. Спасибо!

Amir Mahdi Nassiri 23.05.2018 11:07

После WhatEverYouWant для компиляции отсутствует запятая.

Norbert Hüthmayr 12.03.2021 22:57

В этой ситуации вы можете использовать относительную привязку:

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

Другие вопросы по теме