【问题标题】:XAML Conditional Binding in DataTemplateDataTemplate 中的 XAML 条件绑定
【发布时间】:2014-06-06 17:12:04
【问题描述】:

我在 XAML 中有一个 ListView 的 DataTemplate:

    <DataTemplate x:Key="ResultItemTemplate">
        <Grid Grid.Column="2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto" />
                        <RowDefinition Height="*" />
                        <RowDefinition Height="auto" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding Name}" 
                               Margin="0,10,20,0" 
                               Grid.Column="0"
                               Grid.Row="0"/>

                    <TextBlock Text="{Binding TimeStamp}" 
                               Margin="0,10,10,0" 
                               Grid.Column="1"
                               Grid.Row="0"/>

                    <TextBlock Text="{Binding Text}" 
                               Grid.Column="0"
                               Grid.ColumnSpan="2"
                               Grid.Row="1"
                               TextWrapping="Wrap" 
                               Height="auto"
                               Margin="0,0,10,10"/>

                    <TextBlock Text="{Binding Additional}" 
                               Grid.Column="0"
                               Grid.ColumnSpan="2"
                               Grid.Row="2"
                               TextWrapping="Wrap" 
                               Height="auto"
                               Margin="0,0,10,20" />
                </Grid>
        </DataTemplate>

因此,将此 DataTemplate 应用到我的 ListView,Additional TextBlock 并不存在于每个列表项中。

但是,无论 DataBinding 值是否为 null,Additional TextBlock 都存在间距。
如何仅在存在“附加”绑定属性时才添加文本块?

【问题讨论】:

  • 您可以将 TextBlock 的“可见性”属性绑定到相同的属性(附加)并编写自己的 IValueConverter

标签: c# wpf xaml


【解决方案1】:

您可以编辑文本块的样式并根据绑定的值将可见性设置为折叠或可见。后者可以使用数据触发器来完成。 如果您创建一个属性 ShowAdditional 会更容易,该属性会根据绑定的值返回 true 或 false。通过这种方式,您可以轻松自定义何时显示或不显示。

如下:

<TextBlock Text="{Binding Additional}" Grid.Column="0" Grid.ColumnSpan="2"  Grid.Row="2" TextWrapping="Wrap" Height="auto" Margin="0,0,10,20">
   <TextBlock.Style>
      <Style TargetType="TextBlock">
         <Style.Triggers>
           <DataTrigger Binding="{Binding ShowAddition}" Value="True">
             <Setter Property="Visibility" Value="Visible" />
           </DataTrigger>
           <DataTrigger Binding="{Binding CameraState}" Value="False">
             <Setter Property="Visibility" Value="Collapsed" />
           </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>

将可见性设置为折叠时,整个元素将折叠,包括其边距。

【讨论】:

    【解决方案2】:

    您可以尝试使用BindingBase.TargetNullValue

    <TextBlock Margin="{Binding Path=MyMargin, TargetNullValue=0}" />
    

    预先创建一个属性MyMarginThickness? 类型并带有一些默认值。如果 MyMargin 的值为空值,则取自TargetNullValue

    【讨论】:

      【解决方案3】:

      这是你的转换器:

      namespace ValueConveters
      {
          public class NullToVisibilityConverter : IValueConverter
          {
              public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
              {
                  return value == null ? Visibility.Collapsed : Visibility.Visible;
              }
      
              public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
              {
                  throw new System.NotImplementedException();
              }
          }
      }
      

      这是您的 XAML: 把它放在你的根元素中:

      xmlns:conveters="clr-namespace:ValueConveters"
      

      然后在你的资源中:

      <conveters:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
      <DataTemplate x:Key="ResultItemTemplate">
          <Grid Grid.Column="2">
             <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="auto" />
             </Grid.ColumnDefinitions>
             <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="auto" />
             </Grid.RowDefinitions>
             <TextBlock Text="{Binding Name}" 
                 Margin="0,10,20,0" 
                 Grid.Column="0"
                 Grid.Row="0"/>
             <TextBlock Text="{Binding TimeStamp}" 
                 Margin="0,10,10,0" 
                 Grid.Column="1"
                 Grid.Row="0"/>
             <TextBlock Text="{Binding Text}" 
                 Grid.Column="0"
                 Grid.ColumnSpan="2"
                 Grid.Row="1"
                 TextWrapping="Wrap" 
                 Height="auto"
                 Margin="0,0,10,10"/>
             <TextBlock Text="{Binding Additional}" 
                 Visibility="{Binding Additional,Converter={StaticResource NullToVisibilityConverter}}"
                 Grid.Column="0"
                 Grid.ColumnSpan="2"
                 Grid.Row="2"
                 TextWrapping="Wrap" 
                 Height="auto"
                 Margin="0,0,10,20" />
          </Grid>
      </DataTemplate>
      

      【讨论】:

        【解决方案4】:

        要在Additional 属性不可用时折叠TextBlock,请尝试将TextBlockVisiblity 属性绑定到TargetNullValue 设置为Collapsed。我会建议这样的事情:

        <TextBlock Text="{Binding Additional}" 
                   Grid.Column="0"
                   Grid.ColumnSpan="2"
                   Grid.Row="2"
                   TextWrapping="Wrap" 
                   Height="auto"
                   Margin="0,0,10,20"
                   Visibility="{Binding Additional, TargetNullValue=Collapsed}"
                   />
        

        但事实证明它对我不起作用,原因我不知道。但是以这种方式绑定成功了:

        <TextBlock DataContext="{Binding Additional}"
                   Text="{Binding}" 
                   Grid.Column="0"
                   Grid.ColumnSpan="2"
                   Grid.Row="2"
                   TextWrapping="Wrap" 
                   Height="auto"
                   Margin="0,0,10,20"
                   Visibility="{Binding TargetNullValue=Collapsed}"
                   />
        

        相关问题:

        【讨论】:

          【解决方案5】:

          根据 Flat Eric 的建议 - 字段可以绑定到 IsVisible 属性:

          <Label IsVisible="{Binding Foo}" Text="{Binding Foo}"/>
          

          当值为null时,标签被隐藏。

          【讨论】:

            猜你喜欢
            • 2012-11-14
            • 2013-03-01
            • 2014-03-12
            • 2011-08-16
            • 1970-01-01
            • 1970-01-01
            • 2011-04-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多