WPF-エキスパンダーでHeaderStringFormatが機能しない
-
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には、気を付けるべきこのような落とし穴がかなりあります。例ではそれを示していませんが、念頭に置いてください。ただし、これがあなたの問題だとは思いません。
2番目に注意する点は、これは次とは異なることです
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はこの方法でバインドされず、代わりにHeaderedItemsControlのItemContainerによって提供されるデフォルトのバインドを持ちます。たとえば、TabItemのItemsSourceプロパティを設定すると、ヘッダーとコンテンツバインディングが自動的に接続され、必要な書式設定値を指定するだけです。
最後になりましたが、GroupBoxとTabItemですべてが正常に機能するようになりましたが、エキスパンダーではそれほどうまくいかず、その理由はわかりません。エキスパンダーはContentStringFormatを適切に処理しますが、HeaderContentStringFormatは処理しません。両方がHeaderContentControlから継承することを考えると、これは驚くべきことです。