WPF:嵌套子模板的触发器属性

时间:2017-03-18 14:55:33

标签: wpf templates binding triggers nested

我有一个数据网格,它的一个列中有一个嵌套的数据网格。我需要从子datagid中的行数触发主数据网格行背景颜色。

这是一个简化的例子。

XAML

<Grid>
    <DataGrid x:Name="dataGrid1" ItemsSource="{Binding rigList}"  AutoGenerateColumns="False" CanUserAddRows="false">
        <DataGrid.Resources>
            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Items.Count, ElementName=dataGridInner}" Value="2">
                        <Setter Property="Background" Value="LightBlue"></Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Items.Count, ElementName=dataGridInner}" Value="1">
                        <Setter Property="Background" Value="LightGreen"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Description" Binding="{Binding Description}" Width="*"/>
            <DataGridTemplateColumn Header="Item/Price" Width="220">
                <DataGridTemplateColumn.CellTemplate >
                    <DataTemplate>
                        <DataGrid x:Name="dataGridInner" ItemsSource="{Binding Items}" HeadersVisibility="None" AutoGenerateColumns="False" CanUserAddRows="false" >
                            <DataGrid.Columns>
                                <DataGridTextColumn Binding="{Binding Name}" Width="*"/>
                                <DataGridTextColumn Binding="{Binding Price}" Width="*"/>
                            </DataGrid.Columns>
                        </DataGrid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

C#

public class Item
{
    public string Name { get; set; }
    public int Price { get; set; }
}
public class DataTable
{
    public List<Item> Items { get; set; }
    public string Description { get; set; }
}

public partial class MainWindow : Window
{
    public ObservableCollection<DataTable> itemList { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        itemList = new ObservableCollection<DataTable>
        {
            new DataTable() {
                Items = new List<Item> {
                    new Item { Name = "Phone", Price = 220 },
                    new Item { Name = "Tablet", Price = 350 },
                },
                Description = "Electronic gadgets" },
            new DataTable() {
                Items = new List<Item> {
                    new Item { Name = "Teddy Bear", Price = 2200 },
                },
            Description = "Exclusive teddy bear" }
        };
        dataGrid1.ItemsSource = itemList;
    }
}

Here's the picture of the table this code yields.

因此,通过将触发器放入datagrid的资源,我至少可以使用ElementName到达子数据网格模板。但是setter显然只在子的范围内应用Background属性。我需要的是,如果子数据网格有两行,整个父行将是蓝色。

怎么做?

1 个答案:

答案 0 :(得分:0)

首先,将样式设置为父Grid的RowStyle。那就是你想要设置背景颜色的地方。您不需要将此样式应用于子项,这是您通过在Resources中创建它作为该网格中所有实例的DataGrid行的隐式样式而执行的操作。它的任何子控件(这就是为什么它在子网格上工作)。

其次,您将绑定到父网格行视图模型Items.Count的属性。因此,不需要涉及子网格控制。直接进入填充它的集合。

第三,一旦你使行工作,你会注意到子网格有白色背景。实际上,网格和其中的行具有白色背景。我在子网格的RowStyle属性和子网格本身上添加了一个透明背景的修复程序。

<DataGrid x:Name="dataGrid1" ItemsSource="{Binding rigList}"  AutoGenerateColumns="False" CanUserAddRows="false">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Items.Count}" Value="2">
                    <Setter Property="Background" Value="LightBlue"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding Items.Count}" Value="1">
                    <Setter Property="Background" Value="LightGreen"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Description" Binding="{Binding Description}" Width="*"/>
        <DataGridTemplateColumn Header="Item/Price" Width="220">
            <DataGridTemplateColumn.CellTemplate >
                <DataTemplate>
                    <DataGrid 
                        Background="Transparent"
                        x:Name="dataGridInner" 
                        ItemsSource="{Binding Items}" 
                        HeadersVisibility="None" 
                        AutoGenerateColumns="False" 
                        CanUserAddRows="false" 
                        >
                        <DataGrid.RowStyle>
                            <Style TargetType="DataGridRow">
                                <Setter Property="Background" Value="Transparent" />
                            </Style>
                        </DataGrid.RowStyle>
                        <DataGrid.Columns>
                            <DataGridTextColumn Binding="{Binding Name}" Width="*" />
                            <DataGridTextColumn Binding="{Binding Price}" Width="*"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>