2009-08-01 8 views
32

Creo que esto es posible, pero la forma obvia no funciona.¿Visualizar un DataTemplate predeterminado en un ContentControl cuando su contenido es nulo o está vacío?

Actualmente, estoy haciendo esto:

<ContentControl 
    Content="{Binding HurfView.EditedPart}"> 
    <ContentControl.Resources> 
     <Style 
      TargetType="ContentControl" 
      x:Key="emptytemplate"> 
      <Style.Triggers> 
       <DataTrigger 
        Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Content}" 
        Value="{x:Null}"> 
        <Setter 
         Property="ContentControl.Template"> 
         <Setter.Value> 
          <ControlTemplate> 
           <Grid 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch"> 
            <TextBlock>EMPTY!</TextBlock> 
           </Grid> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ContentControl.Resources> 
</ContentControl> 

ahora no recibo ningún error vinculantes y esto compila. Sin embargo, no produce el resultado esperado. También probé lo obvio:

<DataTemplate DataType="{x:Null}"><TextBlock>Hurf</TextBlock></DataTemplate> 

Esto no se compilará. Y al intentar establecer el contenido dos veces falla también:

<ContentControl 
    Content="{Binding HurfView.EditedPart}"> 
     <TextBlock>DEFAULT DISPLAY</TextBlock> 
</ContentControl> 

¿Puedo hacer esto sin escribir un selector de plantilla personalizado?

Respuesta

45

simple, usted tiene que obligar a la propiedad de contenido en el estilo. Los estilos no sobrescribirán un valor en un control si hay un enlace presente, incluso si el valor se evalúa como nulo. Prueba esto.

<ContentControl> 
    <ContentControl.Style> 
     <Style TargetType="ContentControl"> 
      <Setter Property="Content" Value="{Binding HurfView.EditedPart}" /> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Content}" Value="{x:Null}"> 
        <Setter Property="ContentControl.Template"> 
         <Setter.Value> 
          <ControlTemplate> 
           <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
            <TextBlock>EMPTY!</TextBlock> 
           </Grid> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ContentControl.Style> 
</ContentControl> 
+0

¡Funcionó! Gracias. – Will

+0

No hay problema, es un error muy común que las personas cometen cuando intentan hacer cosas más complejas con estilos y factores desencadenantes. –

+1

Cada vez que vuelvo para esto, voy a dejar un comentario. Gracias. – Will

1

usted podría volver DBNull.Value como el FallbackValue de la unión para el contenido de la ContentControl, y crear un DataTemplate para DBNull:

<DataTemplate DataType="{x:Type system:DBNull}"> 
    <!-- The default template --> 
</DataTemplate> 

... 

<ContentControl Content="{Binding HurfView.EditedPart, FallbackValue={x:Static system:DBNull.Value}}" /> 
+4

Eso es un poco raro ... Yo tenía entendido la El método preferido era devolver [DependencyProperty.UnsetValue] (http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.unsetvalue.aspx). He hecho esto en algunos convertidores de tipo y funcionó bien ... – Will

+2

@ Will, sí, eso probablemente sería mejor. Escribí esa respuesta hace más de un año, y mi comprensión de WPF en ese momento todavía era muy incompleta ... –

+0

Sé que la sensación ... – Will

9

Desde que tropezado con esta pregunta y tenía el mismo problema hoy en día, quería contribuir de otra manera cómo resolví el problema. Dado que no me gusta añadir otro factor desencadenante estilo utilicé la propiedad TargetNullValue que parece ser un poco más legible que la solución aceptada (que funciona sin embargo):

<ContentControl> 
     <ContentControl.Content> 
     <Binding Path="ContentViewModel"> 
      <Binding.TargetNullValue> 
      <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
       <TextBlock>EMPTY!</TextBlock> 
      </Grid> 
      </Binding.TargetNullValue> 
     </Binding> 
     </ContentControl.Content> 
    </ContentControl> 
+0

esta es una solución elegante con TargetNullValue. Buen hallazgo – juFo

+0

Si pudiera dar 10k votaciones al alza ... – curob

+0

Funciona, pero en algunos casos como el mío produce Binding-Errors. Aunque también creo que este es más legible, compruebe si hay nuevos errores de vinculación al usarlo. – Dima

Cuestiones relacionadas