WPF - HeaderStringFormat не работает в Expander - PullRequest
11 голосов
/ 16 ноября 2008

Я не могу найти волшебную комбинацию, чтобы заставить 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>

Что я делаю не так?

1 Ответ

11 голосов
/ 17 ноября 2008

Первое, что нужно отметить, это:

Если вы установите 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.

...