2008-11-16 25 views
11

Parece que no puedo encontrar la combinación mágica para hacer que HeaderStringFormat funcione para un WPF Expander.WPF - HeaderStringFormat No funciona en Expander

Estas son todas las cosas que he intentado:

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

La única manera de obtener una cadena con formato para trabajar correctamente en mi código es hacer esto:

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

Qué am Estoy haciendo mal?

Respuesta

10

La primera cosa a tener en cuenta es la siguiente:

Si se establece la propiedad HeaderTemplate o HeaderTemplateSelector de un HeaderedContentControl , la propiedad HeaderStringFormat es ignorado. MSDN

Hay bastantes trampas de este tipo en WPF a tener en cuenta. No lo demostraste en tu ejemplo, pero solo tenlo en cuenta. Sin embargo, no creo que este sea tu problema.

En segundo lugar hay que destacar es que esto no es lo mismo que:

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

HeaderedContentControl y HeaderStringFormat se utilizan específicamente para las clases que implementan IFormattable. HederStringFormat formatea el encabezado y ContentStringFormat formatea el contenido. El valor de cualquiera de las propiedades es el formato que se pasa a la implementación de las clases if IFormattable.ToString. Puede leer el ejemplo completo en MSDN. Pero aquí está la esencia de cómo hacer que funcione.

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> 

Este TabItem mostrará ahora "Este es mi cadena con formato" en la cabecera, y el contenido será "este es mi cadena sin formato".

Hay un par de cosas para tener en cuenta. Normalmente, estas propiedades se usarían solo en un contexto HeaderedItemsControl. HeaderStringFormat no se vinculará de esta manera, y en su lugar tendrá el enlace predeterminado proporcionado por el ItemContainer de HeaderedItemsControl. Por ejemplo, si configuras la propiedad ItemsSource del TabItem, automáticamente se conectará automáticamente el encabezado y el enlace de contenido, y todo lo que tienes que hacer es proporcionar el valor de formato que deseas.

Por último, pero no menos importante, pude hacer que todo funcionara correctamente con un GroupBox y TabItem, pero no tanta suerte con un expansor y no estoy seguro de por qué. El expansor maneja adecuadamente el ContentStringFormat, pero no el HeaderContentStringFormat. Esto es sorprendente teniendo en cuenta que ambos heredan de HeaderContentControl.

Cuestiones relacionadas