【问题标题】:Datagrid, Merge/Combine rows, cells and columns数据网格,合并/组合行、单元格和列
【发布时间】:2014-08-20 20:49:59
【问题描述】:

我正在尝试准确地完成this 问题所要求的内容,但不幸的是,作为答案提供的代码示例已经消失,而且我也没有使用 WPF Toolkit,这是他所做的问题:

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

我们可以使用 listview 或 listbox.. 来做到这一点吗?或者有没有免费的 具有此功能的可用控件?

我找到了几个使用 DataGridView 控件可以做到这一点的答案,但我不想在 WPF 项目中使用 Form 对象,有没有办法完成这个?

【问题讨论】:

  • prntscr.com/3xzotz 我已经使用 listbox 实现了这个。如果你需要,我会添加代码
  • 如果你能分享它,我会很高兴,也许能让我理解它。

标签: wpf listview datagrid


【解决方案1】:

资源

<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; }
}

【讨论】:

  • 对我来说看起来不错,我没有设法将它实现到 Datagrid 中,但我将使用它来创建一个带有 ListBox 和 Buttons 的 CustomControl 来重新创建一个 Datagrid。感谢您提供这么棒的样品!
  • 我很高兴它有帮助。
【解决方案2】:

对于合并的单元格,绑定其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>

绑定已编入索引,因为CellMarginsThicknessObservableCollection。视图模型是行级的,因此每列绑定到不同的索引。

在这被否决之前,让我说这可能会导致一些不受欢迎的视觉怪癖。让它完美地工作需要一些代码隐藏,例如:

每当列宽发生变化时,单元格边距的负值都需要更新,因此我处理了数据网格的 LayoutUpdated 事件,在该事件中我遍历了列,测量了它们当前的 ActualWidths 并相应地更新了边距。我还更新了BorderThickness 以根据需要显示/隐藏单元格边框。禁用“隐藏”单元格的选择突出显示是另一个技巧。

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

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

【讨论】:

    猜你喜欢
    • 2014-11-22
    • 2018-08-06
    • 2018-07-05
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    • 2012-05-05
    • 2012-02-11
    • 1970-01-01
    相关资源
    最近更新 更多