WPF - HeaderStringFormat在Expander中不起作用

时间:2022-04-12 12:51:42

I can't seem to find the magic combination to make the HeaderStringFormat work for a WPF Expander.

我似乎找不到神奇的组合来使HeaderStringFormat适用于WPF扩展器。

Here are all the things I've tried:

以下是我尝试过的所有内容:

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

The only way I can get a formatted string to work correctly in my code is to do this:

我可以在我的代码中使格式化字符串正常工作的唯一方法是:

<Expander>
    <Expander.Header>
        <TextBlock Text="{Binding Path=MyProperty, StringFormat=Stuff: ({0})}" />
    </Expander.Header>
    <Expander.Content>
        A Expander with working header
    </Expander.Content>
</Expander>

What am I doing wrong?

我究竟做错了什么?

1 个解决方案

#1


10  

First thing to note is this:

首先要注意的是:

If you set the HeaderTemplate or HeaderTemplateSelector property of a HeaderedContentControl, the HeaderStringFormat property is ignored. MSDN

如果设置HeaderedContentControl的HeaderTemplate或HeaderTemplateSelector属性,则忽略HeaderStringFormat属性。 MSDN

There are quite a few gotchas like this in WPF to watch out for. You didn't show that in your example, but just keep it in mind. However, I don't think this is your problem.

在WPF中有很多类似的问题需要注意。您没有在您的示例中显示,但请记住它。但是,我不认为这是你的问题。

Second thing to note is that this isn't the same as:

需要注意的第二点是,这与以下内容不同:

String.Format("My string value is: {0}", myValue");

HeaderedContentControl and HeaderStringFormat are used specifically for classes that implement IFormattable. HederStringFormat formats the header, and ContentStringFormat formats the content. The value of either property is the format that gets passed to your classes implementation if IFormattable.ToString. You can read the full example on MSDN. But here is the gist of how to make it work.

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>

This TabItem will now display "This is my formatted string" in the header, and the content will be "this is my non-formatted string".

此TabItem现在将在标题中显示“这是我的格式化字符串”,内容将是“这是我的非格式化字符串”。

There a couple things to keep in mind. Typically these properties would be used only in an HeaderedItemsControl context. The HeaderStringFormat would not be bound in this way, and instead will have the default binding provided by the ItemContainer of the HeaderedItemsControl. For instance if you set the ItemsSource property of the TabItem, then it will automatically wire up the header and the content binding for you, and all you have to do is supply the formatting value you want.

有几件事需要记住。通常,这些属性仅在HeaderedItemsControl上下文中使用。 HeaderStringFormat不会以这种方式绑定,而是具有HeaderedItemsControl的ItemContainer提供的默认绑定。例如,如果您设置TabItem的ItemsSource属性,那么它将自动为您添加标题和内容绑定,您所要做的就是提供所需的格式化值。

Last, but not least, I was able to get everything working properly with a GroupBox and TabItem, but not so much luck with an expander and I'm not sure why. The expander handles the ContentStringFormat properly, but not the HeaderContentStringFormat. This is suprising considering that the both inherit from HeaderContentControl.

最后,但并非最不重要的是,我能够使用GroupBox和TabItem使一切正常工作,但是使用扩展器并没有太多运气,我不知道为什么。扩展器正确处理ContentStringFormat,但不处理HeaderContentStringFormat。考虑到两者都继承自HeaderContentControl,这令人惊讶。

#1


10  

First thing to note is this:

首先要注意的是:

If you set the HeaderTemplate or HeaderTemplateSelector property of a HeaderedContentControl, the HeaderStringFormat property is ignored. MSDN

如果设置HeaderedContentControl的HeaderTemplate或HeaderTemplateSelector属性,则忽略HeaderStringFormat属性。 MSDN

There are quite a few gotchas like this in WPF to watch out for. You didn't show that in your example, but just keep it in mind. However, I don't think this is your problem.

在WPF中有很多类似的问题需要注意。您没有在您的示例中显示,但请记住它。但是,我不认为这是你的问题。

Second thing to note is that this isn't the same as:

需要注意的第二点是,这与以下内容不同:

String.Format("My string value is: {0}", myValue");

HeaderedContentControl and HeaderStringFormat are used specifically for classes that implement IFormattable. HederStringFormat formats the header, and ContentStringFormat formats the content. The value of either property is the format that gets passed to your classes implementation if IFormattable.ToString. You can read the full example on MSDN. But here is the gist of how to make it work.

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>

This TabItem will now display "This is my formatted string" in the header, and the content will be "this is my non-formatted string".

此TabItem现在将在标题中显示“这是我的格式化字符串”,内容将是“这是我的非格式化字符串”。

There a couple things to keep in mind. Typically these properties would be used only in an HeaderedItemsControl context. The HeaderStringFormat would not be bound in this way, and instead will have the default binding provided by the ItemContainer of the HeaderedItemsControl. For instance if you set the ItemsSource property of the TabItem, then it will automatically wire up the header and the content binding for you, and all you have to do is supply the formatting value you want.

有几件事需要记住。通常,这些属性仅在HeaderedItemsControl上下文中使用。 HeaderStringFormat不会以这种方式绑定,而是具有HeaderedItemsControl的ItemContainer提供的默认绑定。例如,如果您设置TabItem的ItemsSource属性,那么它将自动为您添加标题和内容绑定,您所要做的就是提供所需的格式化值。

Last, but not least, I was able to get everything working properly with a GroupBox and TabItem, but not so much luck with an expander and I'm not sure why. The expander handles the ContentStringFormat properly, but not the HeaderContentStringFormat. This is suprising considering that the both inherit from HeaderContentControl.

最后,但并非最不重要的是,我能够使用GroupBox和TabItem使一切正常工作,但是使用扩展器并没有太多运气,我不知道为什么。扩展器正确处理ContentStringFormat,但不处理HeaderContentStringFormat。考虑到两者都继承自HeaderContentControl,这令人惊讶。