我正在努力完成this问题的请求,但不幸的是,作为答案提供的代码示例已经消失,我也没有使用WPF Toolkit,这里是他所做的问题:
我正在尝试合并WPF工具包datagrid中的单元格。我正在尝试执行如下图所示的操作。我们可以在Winforms datagrid中执行此操作。但是如何使用WPF工具包datagrid执行此操作?。或者是否有任何替代控制..?
我们可以使用listview或listbox来做这件事吗?或者有任何免费的 具有此功能的控件可用吗?
我发现有几个答案可以通过DataGridView控件实现这一点,但是我不想在WPF项目中使用Form对象,有没有办法来实现这个?
答案 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; }
}
答案 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>
绑定被编入索引,因为CellMargins
是ObservableCollection
的{{1}}。 viewmodel是行级的,因此每列都绑定到不同的索引。
在此之前,请允许我说这会导致一些不受欢迎的视觉怪癖。要使其完美运行需要一些代码隐藏,例如:
每当列宽更改时,都需要更新单元格边距的负值,因此我处理了数据网格的Thickness
事件,我在其中迭代了列,测量了它们的当前LayoutUpdated
并更新了边距因此。我同样根据需要更新ActualWidths
以显示/隐藏单元格边框。禁用“隐藏”单元格的选择突出显示是另一种技巧。
请注意,这意味着要跟踪要在代码隐藏中单独合并的单元格(即哪些行视图模型和列索引)。
这种方法很复杂,对于每种情况来说可能不是最容易的,但我发现它对我的目的很有用。我需要一个BorderThickness
用户可以合并/取消合并单元格并创建/删除列,类似于Excel。此外,我希望坚持使用Datagrid
(而非自定义DataGridTextColumns
),因为它们具有内置功能(可识别的键盘编辑命令,复制/粘贴等)。