Wpf 当ContentControl的内容为null或空时,是否在其中显示默认DataTemplate?

Wpf 当ContentControl的内容为null或空时,是否在其中显示默认DataTemplate?,wpf,datatemplate,default-value,contentcontrol,Wpf,Datatemplate,Default Value,Contentcontrol,我认为这是可能的,但显而易见的方法是行不通的 目前,我正在这样做: <ContentControl Content="{Binding HurfView.EditedPart}"> <ContentControl.Resources> <Style TargetType="ContentControl" x:Key="emptytemplate"> <

我认为这是可能的,但显而易见的方法是行不通的

目前,我正在这样做:

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

空的!
我没有收到任何绑定错误,这将编译。然而,它并没有产生预期的结果。我也尝试过显而易见的方法:

<DataTemplate DataType="{x:Null}"><TextBlock>Hurf</TextBlock></DataTemplate>
Hurf
这不会编译。尝试设置内容两次也会失败:

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

默认显示

我可以在不编写自定义模板选择器的情况下执行此操作吗?

您可以返回DBNull.Value作为ContentControl内容绑定的回退值,并为DBNull创建DataTemplate:

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

...

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

...

很简单,您必须在样式中绑定content属性。如果存在绑定,样式将不会覆盖控件上的值,即使该值的计算结果为Null。试试这个

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

空的!

因为我偶然发现了这个问题,今天也遇到了同样的问题,所以我想用另一种方法来解决这个问题。因为我不喜欢添加另一个样式触发器,所以我使用了属性
TargetNullValue
,该属性似乎比公认的解决方案(尽管如此)更具可读性:


空的!

没问题,这是人们在尝试使用样式和触发器执行更复杂的操作时经常犯的错误。每次我回来讨论这个问题时,我都会留下评论。谢谢,我是哈罗塔尔。也是故障转换器的最佳解决方案。只需从转换过程返回
null
,并以这种方式捕获即可。不幸的是,无法通过验证来实现这一点……这是一份不断赠送的礼物,也是Stackoverflow的美妙之处。这次至少有100次。这有点奇怪。。。据我所知,首选的方法是返回。我已经在一些类型转换器中完成了这项工作,它工作得很好…@威尔,是的,那可能会更好。我在一年多前写下了这个答案,当时我对WPF的理解还很不完整…@Will,你能用DependencyProperty添加一个答案吗。UnsetValue@Simon_Weaver嗯,没有?因为我不知道你为什么需要一个?选择的答案是否不正确?我使用了
TargetNullValue={x:Static system:DBNull.Value}
,效果非常好这是一个使用TargetNullValue的优雅解决方案。不错的findWorks,但在像我这样的一些情况下,它会产生绑定错误。虽然我也认为这一点更具可读性,但在使用它时请检查新的绑定错误。另外,请查看此处:[了解
FallbackValue
属性,以防
TargetNullValue
本身无法解决此问题
    <ContentControl>
      <ContentControl.Content>
        <Binding Path="ContentViewModel">
          <Binding.TargetNullValue>
            <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
              <TextBlock>EMPTY!</TextBlock>
            </Grid>
          </Binding.TargetNullValue>
        </Binding>
      </ContentControl.Content>
    </ContentControl>