WPF - HeaderStringFormat Non funziona in Expander
-
08-07-2019 - |
Domanda
Non riesco a trovare la combinazione magica per far funzionare HeaderStringFormat per un Expander WPF.
Ecco tutte le cose che ho provato:
<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>
L'unico modo in cui posso far funzionare correttamente una stringa formattata nel mio codice è fare questo:
<Expander>
<Expander.Header>
<TextBlock Text="{Binding Path=MyProperty, StringFormat=Stuff: ({0})}" />
</Expander.Header>
<Expander.Content>
A Expander with working header
</Expander.Content>
</Expander>
Cosa sto sbagliando?
Soluzione
La prima cosa da notare è questa:
Se si imposta HeaderTemplate o Proprietà HeaderTemplateSelector di a HeaderedContentControl, il La proprietà HeaderStringFormat è ignorato. MSDN
Ci sono parecchi gotcha come questo in WPF a cui fare attenzione. Non lo hai mostrato nel tuo esempio, ma tienilo a mente. Tuttavia, non penso che questo sia il tuo problema.
La seconda cosa da notare è che non è la stessa di:
String.Format("My string value is: {0}", myValue");
HeaderedContentControl e HeaderStringFormat sono utilizzati specificamente per le classi che implementano IFormattable. HederStringFormat formatta l'intestazione e ContentStringFormat formatta il contenuto. Il valore di entrambe le proprietà è il formato che viene passato all'implementazione delle classi se IFormattable.ToString. Puoi leggere l'esempio completo su MSDN . Ma ecco l'essenza di come farlo funzionare.
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>
Questo TabItem ora mostrerà " Questa è la mia stringa formattata " nell'intestazione e il contenuto sarà " questa è la mia stringa non formattata " ;.
Ci sono un paio di cose da tenere a mente. In genere queste proprietà verrebbero utilizzate solo in un contesto HeaderedItemsControl. HeaderStringFormat non verrebbe associato in questo modo e avrà invece l'associazione predefinita fornita da ItemContainer di HeaderedItemsControl. Ad esempio, se imposti la proprietà ItemsSource di TabItem, collegherà automaticamente l'intestazione e l'associazione del contenuto per te e tutto ciò che devi fare è fornire il valore di formattazione che desideri.
Ultimo, ma non meno importante, sono stato in grado di far funzionare tutto correttamente con GroupBox e TabItem, ma non tanta fortuna con un espansore e non sono sicuro del perché. L'expander gestisce correttamente ContentStringFormat, ma non HeaderContentStringFormat. Questo è sorprendente considerando che entrambi ereditano da HeaderContentControl.