WPF - HeaderStringFormat не работает в Expander
-
08-07-2019 - |
Вопрос
Кажется, я не могу найти волшебную комбинацию, чтобы заставить HeaderStringFormat работать для расширителя WPF.
Вот все, что я пробовал:
<Expander Header="{Binding Path=MyProperty, StringFormat=Stuff: ({0})}" >
<TextBlock Text="Some Content" />
</Expander>
<Expander HeaderStringFormat="{}Stuff ({0})" Header="{Binding Path=MyProperty}">
<TextBlock Text="Some More Content" />
</Expander>
<Expander HeaderStringFormat="{}Stuff ({0:0})" Header="{Binding Path=MyProperty}">
<TextBlock Text="Even More Content" />
</Expander>
Единственный способ заставить правильно отформатированную строку работать в моем коде - это сделать это:
<Expander>
<Expander.Header>
<TextBlock Text="{Binding Path=MyProperty, StringFormat=Stuff: ({0})}" />
</Expander.Header>
<Expander.Content>
A Expander with working header
</Expander.Content>
</Expander>
Что я делаю не так?
Решение
Первое, на что стоит обратить внимание:
Если вы установите HeaderTemplate или Свойство HeaderTemplateSelector объекта HeaderedContentControl, Свойство HeaderStringFormat равно игнорируются. MSDN
В WPF есть несколько таких ошибок, на которые стоит обратить внимание. Вы не показали это в своем примере, но просто имейте это в виду. Однако я не думаю, что это ваша проблема.
Второе, на что следует обратить внимание: это не то же самое, что:
String.Format("My string value is: {0}", myValue");
HeaderedContentControl и HeaderStringFormat используются специально для классов, которые реализуют IFormattable. HederStringFormat форматирует заголовок, а ContentStringFormat форматирует содержимое. Значением любого свойства является формат, который передается в реализацию ваших классов, если IFormattable.ToString. Вы можете прочитать полный пример на MSDN . Но вот суть того, как заставить это работать.
public class MyTestClass : IFormattable
{
#region IFormattable Members
public string ToString(string format, IFormatProvider formatProvider)
{
if(format == "n")
{
return "This is my formatted string";
}
else
{
return "this is my non-formatted string";
}
}
#endregion
}
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderStringFormat" Value="n" />
<Setter Property="ContentStringFormat" Value="" />
</Style>
<TabControl>
<TabItem Header="{Binding Content, RelativeSource={RelativeSource Self}}">
<local:MyTestClass />
</TabItem>
</TabControl>
Этот TabItem теперь будет отображать " Это моя отформатированная строка " в заголовке, и содержимое будет «это моя неформатированная строка». Р>
Есть пара вещей, о которых нужно помнить. Обычно эти свойства используются только в контексте HeaderedItemsControl. HeaderStringFormat не будет привязан таким образом, и вместо этого будет иметь привязку по умолчанию, предоставляемую ItemContainer объекта HeaderedItemsControl. Например, если вы установите свойство ItemsSource для TabItem, то оно автоматически подключит заголовок и привязку содержимого для вас, и все, что вам нужно сделать, это указать требуемое значение форматирования.
Наконец, но не в последнюю очередь, я смог заставить все работать правильно с GroupBox и TabItem, но не так много удачи с расширителем, и я не уверен почему. Расширитель правильно обрабатывает ContentStringFormat, но не HeaderContentStringFormat. Это удивительно, учитывая, что оба наследуют от HeaderContentControl.