【问题标题】:Display a default DataTemplate in a ContentControl when its content is null or empty?当 ContentControl 的内容为空或为空时,在 ContentControl 中显示默认的 DataTemplate?
【发布时间】:2010-11-16 01:53:23
【问题描述】:

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

目前,我正在这样做:

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

这不会编译。并且尝试设置内容两次也失败了:

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

我可以在不编写自定义模板选择器的情况下做到这一点吗?

【问题讨论】:

    标签: wpf datatemplate default-value contentcontrol


    【解决方案1】:

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

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

    【讨论】:

    • 这是一个使用 TargetNullValue 的优雅解决方案。不错的发现
    • 有效,但在某些情况下,例如我的情况,它会产生绑定错误。虽然我也认为这个更具可读性,但在使用时检查新的 Binding-Errors。
    • 也看看这里:[stackoverflow.com/questions/22315699/… 了解FallbackValue 属性,以防TargetNullValue 单独解决问题
    【解决方案2】:

    简单,你必须在样式中绑定内容属性。如果存在绑定,则样式不会覆盖控件上的值,即使该值的计算结果为 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>
    

    【讨论】:

    • 没问题,这是人们在尝试使用样式和触发器做更复杂的事情时常犯的错误。
    • 每次我回来都会留下评论。谢谢。
    • 你晕。失败的转换器的最佳解决方案也是如此。只需从转换过程中返回null 并以这种方式捕获它。不幸的是,无法使用验证来做到这一点......
    • 这是不断给予的礼物,也是 Stackoverflow 的美丽。
    • 嗯,这次至少有 100 个代表。
    【解决方案3】:

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

    <DataTemplate DataType="{x:Type system:DBNull}">
        <!-- The default template -->
    </DataTemplate>
    
    ...
    
    <ContentControl Content="{Binding HurfView.EditedPart, FallbackValue={x:Static system:DBNull.Value}}" />
    

    【讨论】:

    • 这有点奇怪......据我了解,首选方法是返回DependencyProperty.UnsetValue。我已经在一些类型转换器中做到了这一点,并且效果很好......
    • @Will,是的,那可能会更好。那个答案是我一年多前写的,当时对WPF的理解还很不完整……
    • @Will 你能用 DependencyProperty.UnsetValue 添加答案吗
    • @Simon_Weaver 嗯,不是吗?因为我不知道你为什么需要一个?选择的答案不正确吗?
    • 我用过TargetNullValue={x:Static system:DBNull.Value}&lt;DataTemplate DataType="{x:Type system:DBNull}"&gt;,效果很好
    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多