¿Mostrar un DataTemplate predeterminado en un ContentControl cuando su contenido es nulo o está vacío?
-
07-07-2019 - |
Pregunta
Creo que esto es posible, pero la forma obvia no está funcionando.
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>
No recibo ningún error vinculante y esto se 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á. E intentar configurar el contenido dos veces también falla:
<ContentControl
Content="{Binding HurfView.EditedPart}">
<TextBlock>DEFAULT DISPLAY</TextBlock>
</ContentControl>
¿Puedo hacer esto sin escribir un selector de plantilla personalizado?
Solución
Simple, debe vincular 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>
Otros consejos
Dado que me topé con esta pregunta y tuve el mismo problema hoy, quería contribuir de otra manera para resolver el problema. Como no me gustaba agregar otro desencadenador de estilo, utilicé la propiedad TargetNullValue
que parece ser un poco más legible que la solución aceptada (que funciona de todos modos):
<ContentControl>
<ContentControl.Content>
<Binding Path="ContentViewModel">
<Binding.TargetNullValue>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock>EMPTY!</TextBlock>
</Grid>
</Binding.TargetNullValue>
</Binding>
</ContentControl.Content>
</ContentControl>
Puede devolver DBNull.Value como FallbackValue del enlace para el contenido de 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}}" />