如何在 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
,它应该显示多个绑定属性(这是我无法完成的)。在DataTrigger
Setter
下如何使用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?
WPF - 如何结合 DataTrigger 和 Trigger?
如何使用 DataTrigger 更改 ItemsControl 中的 ItemsPanel?