如何在 DataTrigger Setter 下使用由多个 TextBlock 组成的 WrapPanel

Posted

技术标签:

【中文标题】如何在 DataTrigger Setter 下使用由多个 TextBlock 组成的 WrapPanel【英文标题】:How to use WrapPanel that consists of many TextBlocks under DataTrigger Setter 【发布时间】:2021-06-09 10:15:35 【问题描述】:

我有一个DataGrid,其中包含一些列。在一个DataGridTemplateColumn 中,我想使用一个条件。如果条件是False,它应该显示一个绑定属性。如果条件是True,它应该显示多个绑定属性(这是我无法完成的)。在DataTriggerSetter下如何使用WrapPanel

我的 XAML 代码:

<DataGrid x:Name="DG_SipList"  ItemsSource="Binding Items3" Margin="0 8 0 0"  CanUserSortColumns="False"  CanUserAddRows="False"  AutoGenerateColumns="False" VerticalAlignment="Top" HorizontalAlignment="Left"   materialDesign:DataGridAssist.CellPadding="13 8 8 8"  materialDesign:DataGridAssist.ColumnHeaderPadding="8" IsReadOnly="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" >
    <DataGrid.Resources>
        <Style TargetType="TextBlock" x:Key="cfgText">
            <Style.Triggers>
                <DataTrigger Binding="Binding Tag, RelativeSource=RelativeSource Self" Value="False">
                    <Setter Property="FontWeight" Value="Bold"/>
                    <Setter Property="FontStyle" Value="Italic"/>
                    <Setter Property="TextDecorations" Value="Underline"/>
                    <Setter Property="Foreground" Value="Red"/>
                    <Setter  Property="HorizontalAlignment"  Value="Left" />
                    <Setter Property="TextWrapping" Value="WrapWithOverflow" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <Style TargetType="TextBlock" x:Key="cfgText2">
            <Style.Triggers>
                <DataTrigger Binding="Binding Tag, RelativeSource=RelativeSource Self" Value="True">
                    <Setter Property="FontWeight" Value="Bold"/>
                    <Setter Property="FontStyle" Value="Italic"/>
                    <Setter Property="Foreground" Value="Red"/>
                    <Setter  Property="HorizontalAlignment"  Value="Left" />
                    <Setter Property="TextWrapping" Value="WrapWithOverflow" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.Resources>

    <DataGrid.Columns>
        <DataGridTemplateColumn Header="START" IsReadOnly="False">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox x:Name="cb_MontajStart" Checked="cb_MontajStart_Checked" Unchecked="cb_MontajStart_Unchecked" IsChecked="Binding LISTE_MONTAJ_START" HorizontalAlignment="Center"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTemplateColumn Header="ID">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="Binding Path=LISTE_KIMLIK" Tag="Binding Path=LISTE_MONTAJ_START" Style="StaticResource cfgText2"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        
        <DataGridTemplateColumn Header="PRODUCT" MaxWidth="450">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock>
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="Binding konfTanim" Value="False">
                                        <Setter Property="Text" Value="Binding LISTE_URUN"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="Binding konfTanim" Value="True">
                                        <Setter>
<!--This is what I can not combine more than one textblock under Datatrigger Setter-->
                                             <WrapPanel Orientation="Horizontal" MaxWidth="450">
                        <TextBlock Text="Binding Path=yeni_ModelTanim"/>
                        <TextBlock Text="Binding Path=MT4" Tag="Binding Path=monStd4" Style="StaticResource cfgText"/>
                        <TextBlock Text="Binding Path=MT5" Tag="Binding Path=monStd5" Style="StaticResource cfgText"/>
                        <TextBlock Text="Binding Path=MT6" Tag="Binding Path=monStd6" Style="StaticResource cfgText"/>  
                                            </WrapPanel>   
                                        </Setter>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <!-- ........................................................... -->
        <DataGridTemplateColumn x:Name="txt_Configuration"  Header="configuration" >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <WrapPanel Orientation="Horizontal" MaxWidth="450">
                        <TextBlock Text="Binding Path=yeni_ModelTanim"/>
                        <TextBlock Text="Binding Path=MT4" Tag="Binding Path=monStd4" Style="StaticResource cfgText"/>
                        <TextBlock Text="Binding Path=MT5" Tag="Binding Path=monStd5" Style="StaticResource cfgText"/>
                        <TextBlock Text="Binding Path=MT6" Tag="Binding Path=monStd6" Style="StaticResource cfgText"/>  
                    </WrapPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
      </DataGrid.Columns>
</DataGrid>

【问题讨论】:

你可以定义一个DataTemplateSelector 提到here 然后设置DataGridTemplateColumn.CellTemplateSelector = toYourTemplateSelector 只有使用 XAML(不使用 C#)就没有其他方法可以做到这一点吗? 【参考方案1】:

如果有多个相同类型的不同表示,根据标志或其他属性,您必须为每个表示实现自定义DataTemplateSelector 和数据模板,例如:

<DataTemplate x:Key="KonfTanimFalseTemplate">
   <TextBlock Text="Binding LISTE_URUN"/>
</DataTemplate>
<DataTemplate x:Key="KonfTanimTrueTemplate">
   <WrapPanel Orientation="Horizontal" MaxWidth="450">
      <TextBlock Text="Binding Path=yeni_ModelTanim"/>
      <TextBlock Text="Binding Path=MT4" Tag="Binding Path=monStd4" Style="StaticResource cfgText"/>
      <TextBlock Text="Binding Path=MT5" Tag="Binding Path=monStd5" Style="StaticResource cfgText"/>
      <TextBlock Text="Binding Path=MT6" Tag="Binding Path=monStd6" Style="StaticResource cfgText"/>
   </WrapPanel>  
</DataTemplate>

数据模板选择器检查konfTanim 属性并返回适当的数据模板。

public class KonfTanimDataTemplateSelector : DataTemplateSelector

   public override DataTemplate SelectTemplate(object item, DependencyObject container)
   
      if (!(container is FrameworkElement frameworkElement) || !(item is YourItemType yourItem))
         return null;

      var dataTemplateName = yourItem.konfTanim ? "KonfTanimTrueTemplate" : "KonfTanimFalseTemplate";
      return (DataTemplate) frameworkElement.FindResource(dataTemplateName);
   

您还可以通过属性传入模板名称以避免在此处对它们进行硬编码。这有助于在您的应用程序中重用选择器。在您的DataGrid 中,您可以使用选择器实例将数据模板添加到Resources,并在模板列中使用它,如下所示:

<DataGrid ItemsSource="Binding YourItemTypeList" AutoGenerateColumns="False">
   <DataGrid.Resources>
      <DataTemplate x:Key="KonfTanimFalseTemplate">
         <TextBlock Text="Binding LISTE_URUN"/>
      </DataTemplate>
      <DataTemplate x:Key="KonfTanimTrueTemplate">
         <WrapPanel Orientation="Horizontal" MaxWidth="450">
            <TextBlock Text="Binding Path=yeni_ModelTanim"/>
            <TextBlock Text="Binding Path=MT4" Tag="Binding Path=monStd4" Style="StaticResource cfgText"/>
            <TextBlock Text="Binding Path=MT5" Tag="Binding Path=monStd5" Style="StaticResource cfgText"/>
            <TextBlock Text="Binding Path=MT6" Tag="Binding Path=monStd6" Style="StaticResource cfgText"/>
         </WrapPanel>  
      </DataTemplate>
      <local:KonfTanimDataTemplateSelector x:Key="KonfTanimDataTemplateSelector"/>
   </DataGrid.Resources>
   <DataGrid.Columns>
      <DataGridTemplateColumn CellTemplateSelector="StaticResource KonfTanimDataTemplateSelector"/>
   </DataGrid.Columns>
</DataGrid>

只有使用 XAML(不使用 C#),我没有其他方法可以做到这一点吗?

对于复杂条件使用数据模板选择器并没有什么不好。

Choosing a DataTemplate Based on Properties of the Data Object

然而,通常有一个标志来确定一个对象的类型,这表明相应的类应该被分成两种不同的类型。在这种情况下,您可以为这两种类型创建具有特定 DataType 的数据模板。不幸的是,按类型的自动数据模板选择在其他项目控件中有效,但在DataGrid 或更具体地说是模板列中,您必须使用变通方法,这可能比仅创建一个更麻烦也可以在其他列中重用的选择器。

【讨论】:

以上是关于如何在 DataTrigger Setter 下使用由多个 TextBlock 组成的 WrapPanel的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Binding="Binding" 以编程方式创建 DataTrigger?

如何将参数传递给 DataTrigger?

WPF - 如何结合 DataTrigger 和 Trigger?

如何使用 DataTrigger 更改 ItemsControl 中的 ItemsPanel?

如何将触发器与 SourceName 和 DataTrigger 结合使用?

WPF DataGrid - 如何设置正确的 DataTrigger 绑定到单元格的数据源(而不是行的源)