Exibir um datatemplate padrão em um contentControl quando seu conteúdo estiver nulo ou vazio?
-
07-07-2019 - |
Pergunta
Eu acho que isso é possível, mas a maneira óbvia não está funcionando.
Atualmente, estou fazendo isso:
<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>
Não estou recebendo erros vinculativos e isso compila. No entanto, ele não produz o resultado esperado. Eu também tentei o óbvio:
<DataTemplate DataType="{x:Null}"><TextBlock>Hurf</TextBlock></DataTemplate>
Isso não vai compilar. E tentar definir o conteúdo também falha duas vezes:
<ContentControl
Content="{Binding HurfView.EditedPart}">
<TextBlock>DEFAULT DISPLAY</TextBlock>
</ContentControl>
Posso fazer isso sem escrever um seletor de modelo personalizado?
Solução
Simples, você precisa vincular a propriedade de conteúdo no estilo. Os estilos não substituem um valor em um controle se houver um presente vinculativo, mesmo que o valor seja avaliado como nulo. Tente isso.
<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>
Outras dicas
Desde que me deparei com essa pergunta e tive o mesmo problema hoje, eu queria contribuir de outra maneira como resolvi o problema. Como eu não gostava de adicionar outro gatilho de estilo, usei a propriedade TargetNullValue
O que parece ser um pouco mais legível do que a solução aceita (que funciona, no entanto):
<ContentControl>
<ContentControl.Content>
<Binding Path="ContentViewModel">
<Binding.TargetNullValue>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock>EMPTY!</TextBlock>
</Grid>
</Binding.TargetNullValue>
</Binding>
</ContentControl.Content>
</ContentControl>
Você pode retornar dbnull.value como o FallbackValue da ligação para o conteúdo do ContentControl e criar um DataTemplate para DBNull:
<DataTemplate DataType="{x:Type system:DBNull}">
<!-- The default template -->
</DataTemplate>
...
<ContentControl Content="{Binding HurfView.EditedPart, FallbackValue={x:Static system:DBNull.Value}}" />