Datagrid,Merge / Combine行,单元格和列

时间:2014-06-30 13:06:24

标签: wpf listview datagrid

我正在努力完成this问题的请求,但不幸的是,作为答案提供的代码示例已经消失,我也没有使用WPF Toolkit,这里是他所做的问题:

  

我正在尝试合并WPF工具包datagrid中的单元格。我正在尝试执行如下图所示的操作。我们可以在Winforms datagrid中执行此操作。但是如何使用WPF工具包datagrid执行此操作?。或者是否有任何替代控制..?

     

我们可以使用listview或listbox来做这件事吗?或者有任何免费的   具有此功能的控件可用吗?

enter image description here

我发现有几个答案可以通过DataGridView控件实现这一点,但是我不想在WPF项目中使用Form对象,有没有办法来实现这个?

2 个答案:

答案 0 :(得分:8)

<强>林资源

<Window.Resources>
    <Color x:Key="customBlue"  A="255"   R="54" G="95" B="177"  />
    <SolidColorBrush x:Key="customBlueBrush" Color="{StaticResource customBlue}"></SolidColorBrush>
    <SolidColorBrush x:Key="customBlueBrushOpacity" Color="LightGray" Opacity="0.11"></SolidColorBrush>
    <Style x:Key="calcyListbox"  TargetType="ListBox">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <Grid >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="35"></RowDefinition>
                            <RowDefinition></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="0" Height="30"  VerticalAlignment="Top" Background="{StaticResource customBlueBrush}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="Manufacturer" FontSize="14" FontFamily="Segoe Ui Dark" Foreground="White" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" ></TextBlock>
                            <TextBlock Text="Name" FontSize="14" FontFamily="Segoe Ui Dark" Foreground="White" SnapsToDevicePixels="True"  HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1"></TextBlock>
                            <TextBlock Text="CPU" FontSize="14" FontFamily="Segoe Ui Dark"  Foreground="White" SnapsToDevicePixels="True"  HorizontalAlignment="Center" VerticalAlignment="Center"  Grid.Column="2"></TextBlock>
                            <TextBlock Text="RAM" FontSize="14" FontFamily="Segoe Ui Dark"  Foreground="White" SnapsToDevicePixels="True"  HorizontalAlignment="Center" VerticalAlignment="Center"  Grid.Column="3"></TextBlock>
                            <TextBlock Text="Price" FontSize="14" FontFamily="Segoe Ui Dark"  Foreground="White" SnapsToDevicePixels="True"  HorizontalAlignment="Center" VerticalAlignment="Center"  Grid.Column="4"></TextBlock>
                        </Grid>
                        <Border Grid.Row="1" SnapsToDevicePixels="True"  Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0">
                            <ScrollViewer x:Name="ScrollViewer"  Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="0">
                                <ItemsPresenter />
                            </ScrollViewer>
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="noStyleToListboxItem" TargetType="ListBoxItem">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border>
                        <ContentPresenter></ContentPresenter>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<强> XAML

<ListBox  MaxHeight="300" ItemsSource="{Binding ManufacturerList}" Background="{StaticResource customBlueBrushOpacity}"  x:Name="ManufacturerListBox" ScrollViewer.VerticalScrollBarVisibility="Auto" Style="{StaticResource calcyListbox}" ItemContainerStyle="{StaticResource noStyleToListboxItem}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="4*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Company}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <Border BorderThickness="0,0,0,1" BorderBrush="Black" ></Border>
                <ListBox Grid.Column="1" BorderThickness="1,0,1,1" Background="{StaticResource customBlueBrushOpacity}" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Models}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <Border BorderThickness="0,0,1,0" BorderBrush="Black" Margin="-2" Grid.Column="0"></Border>
                                <Border BorderThickness="0,0,1,0" BorderBrush="Black" Margin="-2" Grid.Column="1"></Border>
                                <Border BorderThickness="0,0,1,0" BorderBrush="Black" Margin="-2" Grid.Column="2"></Border>
                                <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0"/>
                                <TextBlock Text="{Binding CPU}" HorizontalAlignment="Center" VerticalAlignment="Center"  Grid.Column="1"/>
                                <TextBlock Text="{Binding Ram}" HorizontalAlignment="Center" VerticalAlignment="Center"  Grid.Column="2"/>
                                <TextBlock Text="{Binding price}" HorizontalAlignment="Center" VerticalAlignment="Center"  Grid.Column="3"/>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

<强> c#中

        InitializeComponent();
        List<Manufacturer> ManufacturerList = new List<Manufacturer>();

        ManufacturerList.Add(new Manufacturer()
        {
            Company = "DEll",
            Models = new List<Model>(){new Model(){CPU = "T7250", Name = "Inspiron1525", price =234434 , Ram= "2048 MB" },
                                       new Model(){CPU = "T5750", Name = "Studio 1535", price =234443 , Ram= "2048 MB" },
                                       new Model(){CPU = "T5780", Name = "Vastro 1510", price =234434 , Ram= "2048 MB" },}
        });

        ManufacturerList.Add(new Manufacturer()
        {
            Company = "Lenovo",
            Models = new List<Model>(){new Model(){CPU = "T1230", Name = "l123", price =23546454 , Ram= "1024 MB" },
                                      new Model(){CPU = "T1230", Name = "l1423", price =2346456 , Ram= "1024 MB" },
                                      new Model(){CPU = "T1230", Name = "ldf123", price =2344646 , Ram= "1024 MB" },}
        });

        ManufacturerListBox.ItemsSource = ManufacturerList;

public class Manufacturer
{
    public string Company { get; set; }
    public List<Model> Models { get; set; }
}

public class Model
{
    public string Name { get; set; }
    public string Ram { get; set; }
    public double price { get; set; }
    public string CPU { get; set; }
}

enter image description here

答案 1 :(得分:0)

对于合并的单元格,绑定其Margin并将其设置为等于相关合并单元格的总宽度/高度的负值 - 然后单元格将溢出并覆盖相邻单元格。

    <Style TargetType="DataGridCell"> 
        <Setter Property="BorderThickness" Value="{{Binding BorderThickness[5], Mode=OneWay}}"/> 
        <Setter Property="Margin" Value="{{Binding CellMargins[5], Mode=OneWay}}"/>
        <Setter Property="Block.TextAlignment" Value="Center"/>             
    </Style>

绑定被编入索引,因为CellMarginsObservableCollection的{​​{1}}。 viewmodel是行级的,因此每列都绑定到不同的索引。

在此之前,请允许我说这会导致一些不受欢迎的视觉怪癖。要使其完美运行需要一些代码隐藏,例如:

每当列宽更改时,都需要更新单元格边距的负值,因此我处理了数据网格的Thickness事件,我在其中迭代了列,测量了它们的当前LayoutUpdated并更新了边距因此。我同样根据需要更新ActualWidths以显示/隐藏单元格边框。禁用“隐藏”单元格的选择突出显示是另一种技巧。

请注意,这意味着要跟踪要在代码隐藏中单独合并的单元格(即哪些行视图模型和列索引)。

这种方法很复杂,对于每种情况来说可能不是最容易的,但我发现它对我的目的很有用。我需要一个BorderThickness用户可以合并/取消合并单元格并创建/删除列,类似于Excel。此外,我希望坚持使用Datagrid(而非自定义DataGridTextColumns),因为它们具有内置功能(可识别的键盘编辑命令,复制/粘贴等)。