Следующий код имеет простую привязку, которая связывает текст 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 всплывающая подсказка показывает только значение привязки, а не значение в строковом формате. Есть идеи?





Всплывающие подсказки в 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 в этом случае не может получить доступ к внешнему элементу.
Обратите внимание, что {} требуется только тогда, когда вы помещаете {0} в начало строки, поэтому вам нужно, чтобы он отличался от других разметок xaml.
Разум = взорван. Я просто нажал на это и подумал: «Уаааат?»
Меня очень огорчило то, что строковый формат не «просто работает», когда не указан конвертер. Пришлось написать собственный конвертер строкового формата. МС снова бросает мяч ...
Здесь нельзя использовать ни ElementName, ни RelativeSource (с AncestorType), когда я пытался. Итак, как это вообще может быть связано с чем-то значимым?
Это решило мою проблему с форматированием содержимого кнопки. В других примерах, которые я нашел, просто используется StringFormat с Binding и ничего не упоминается о различиях между элементами управления содержимым и другими элементами управления.
StringFormat будет применяться только в том случае, если TargetType является строковым типом. ToolTip Содержимое относится к типу object.
Следующее решение является многословным, но оно работает.
<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: «лучше» в глазах смотрящего, и можно отметить свой вопрос принятым ответом
@Shimmy Хуже того, в его ответе есть шутка про 42.
@Andomar, лучше люди решают своими голосами, особенно здесь, это почти тот же ответ. заставлять людей отвечать на ваши вопросы, а затем копировать их ответы и завоевывать репутацию, поскольку это совершенно неправильное отношение.
Ваш код может быть таким коротким:
<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 меня сбила с толку. Этот ответ работал в моем случае, тогда как другие нет.
Как сказал Мэтт, всплывающая подсказка может содержать что угодно внутри, поэтому для вас вы можете привязать 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>
Работает как положено.
Самый точный ответ .. Спасибо!
После WhatEverYouWant для компиляции отсутствует запятая.
В этой ситуации вы можете использовать относительную привязку:
<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>
Мне не удалось заставить работать ни одно из предложенных ниже решений, но это сработало: stackoverflow.com/questions/4498649/…