最近在做项目时,遇到的一个需求,表格动态单元格合并处理问题,表头合并单元格,但是行也有表头,进行处理时,想到了两个ListView进行分成左右处理单元格,并且做到自适应。
实现图
xaml
<Window x:Class="MergeCells.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MergeCells"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Margin="10" x:Name="DataGrid" >
<Grid >
<Grid.Resources>
<Style TargetType="ItemsControl" x:Key="PressureItemControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel></VirtualizingStackPanel>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding}"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border Width="212" Name="xBorder" BorderThickness="0,1,1,1" BorderBrush="Black" >
<Grid Height="41" >
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" BorderThickness="0,0,1,0" BorderBrush="Black">
<Label Width="106" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Background="Transparent" VerticalContentAlignment="Center" Content="{Binding GasTypeOfCurrent}"
FontSize="14" HorizontalContentAlignment="Left"></Label>
</Border>
<Border Grid.Row="0" Grid.Column="1" BorderThickness="0,0,1,0" BorderBrush="Black">
<Label Width="106" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="Transparent" Content="{Binding GasTypeOfPrevious}"
FontSize="14" VerticalContentAlignment="Center" HorizontalContentAlignment="Left"></Label>
</Border>
</Grid>
</Border>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" TargetName="xBorder" Value="{DynamicResource DefaultButtonBackgroud}" ></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" TargetName="xBorder" Value="{DynamicResource TextBoxBackground}" ></Setter>
</Trigger>
<DataTrigger Binding="{Binding GasTypeOfCurrent}" Value="Current">
<Setter Property="Background" TargetName="xBorder" Value="{DynamicResource DefaultHeaderBackground}"/>
</DataTrigger>
<DataTrigger Binding="{Binding GasTypeOfPrevious}" Value="Previous">
<Setter Property="Background" TargetName="xBorder" Value="{DynamicResource DefaultHeaderBackground}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border BorderBrush="Black"
BorderThickness="0,1,0,0">
<StackPanel Orientation="Horizontal">
<ItemsPresenter/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ItemsControl" x:Key="PressureDataControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"></VirtualizingStackPanel>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border Width="212" Background="{DynamicResource DefaultHeaderBackground}" BorderBrush="Black"
BorderThickness="1,1,1,0"
Margin="-6,-2,-6,-2" >
<StackPanel VerticalAlignment="Center" >
<TextBox IsReadOnly="True" Height="23" Width="212" Background="Transparent" VerticalContentAlignment="Center" BorderThickness="0" HorizontalContentAlignment="Center" Text="{Binding Columes}"
FontSize="14" ></TextBox>
<ItemsControl AlternationCount="2" Style="{StaticResource PressureItemControl}" ItemsSource="{Binding GasHeaderName}"></ItemsControl>
</StackPanel>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border BorderBrush="Black"
BorderThickness="0,0,1,0">
<StackPanel Orientation="Horizontal">
<ItemsPresenter/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ItemsControl" x:Key="HeaderPressureItemsControl">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border Width="92" Name="xBorder" BorderBrush="Black"
BorderThickness="1,1,1,0"
Margin="-6,-2,-6,-2">
<StackPanel VerticalAlignment="Center">
<Label Name="LabelHeader" Background="Transparent" VerticalContentAlignment="Center" HorizontalAlignment="Center" Content="{Binding GasHeader}"
FontSize="14" ></Label>
</StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Index}" Value="0">
<Setter Property="Background" TargetName="xBorder" Value="{DynamicResource TextBoxBackground}"/>
<Setter Property="Height" Value="39"/>
</DataTrigger>
<DataTrigger Binding="{Binding Index}" Value="2">
<Setter Property="Background" TargetName="xBorder" Value="{DynamicResource DefaultHeaderBackground}"/>
<Setter Property="Height" Value="20"/>
</DataTrigger>
<DataTrigger Binding="{Binding Index}" Value="1">
<Setter Property="Background" TargetName="xBorder" Value="{DynamicResource DefaultHeaderBackground}" />
<Setter Property="Height" Value="39"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border BorderBrush="Black"
BorderThickness="0,1,0,0">
<StackPanel Orientation="Vertical">
<ItemsPresenter/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="9*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ScrollViewer Height="Auto" HorizontalAlignment="Right" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" Grid.Column="0" >
<ListView BorderBrush="Black" Grid.Column="0" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" Width="92"
ItemsSource="{Binding Flow}" Style="{StaticResource HeaderPressureItemsControl}">
</ListView>
</ScrollViewer>
<ScrollViewer Grid.Column="1" HorizontalScrollBarVisibility="Visible" >
<ListView HorizontalAlignment="Center" BorderBrush="Black" VerticalAlignment="Top"
ItemsSource="{Binding GasModel}" Style="{StaticResource PressureDataControl}" >
</ListView>
</ScrollViewer>
</Grid>
</ScrollViewer>
</Grid>
</Window>
xaml.cs
namespace MergeCells
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = MainViewModel.Instance; //绑定MainViewModel单例
}
}
public class MainViewModel {
public MainViewModel()
{
}
private ObservableCollection<GasFlowHeader> _Flow = null;
public ObservableCollection<GasFlowHeader> Flow
{
get
{
if (_Flow == null)
{
_Flow = new ObservableCollection<GasFlowHeader>();
}
return _Flow;
}
set
{
_Flow = value;
}
}
private ObservableCollection<GasModel> _GasModel = null;
public ObservableCollection<GasModel> GasModel
{
get
{
if (_GasModel == null)
{
_GasModel = new ObservableCollection<GasModel>();
}
return _GasModel;
}
set
{
_GasModel = value;
}
}
private static MainViewModel _instance = null;
public static MainViewModel Instance
{
get {
if (_instance == null)
{
_instance = new MainViewModel();
ObservableCollection<GasFlowHeader> Flow = new ObservableCollection<GasFlowHeader>();
ObservableCollection<GasModel> GasModel = new ObservableCollection<GasModel>();
Flow.Add(new GasFlowHeader { Index = 2 });
Flow.Add(new GasFlowHeader { GasHeader = "row1", Index = 1 });
Flow.Add(new GasFlowHeader { GasHeader = "row2", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row3", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row4", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row5", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row6", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row7", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row8", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row9", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row10", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row11", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row12", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row13", Index = 0 });
Flow.Add(new GasFlowHeader { GasHeader = "row14", Index = 0 });
ObservableCollection<GasHeaderName> gasHeaderName = new ObservableCollection<GasHeaderName>();
gasHeaderName.Add(new GasHeaderName
{ GasTypeOfCurrent = "name1", GasTypeOfPrevious = "name2" });
GasModel.Add(new GasModel { Columes = "Test1", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test2", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test3", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test4", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test5", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test6", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test7", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test8", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test9", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test10", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test11", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test12", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test13", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test14", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test15", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test16", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test17", GasHeaderName = gasHeaderName });
GasModel.Add(new GasModel { Columes = "Test18", GasHeaderName = gasHeaderName });
_instance.Flow = Flow;
_instance.GasModel = GasModel;
}
return _instance;
}
}
}
public class GasFlowHeader
{
/// <summary>
/// GasFlowHeader Filed
/// </summary>
public string GasHeader { get; set; }
/// <summary>
/// GasFlowHeader Filed
/// </summary>
public int Index { get; set; }
}
public class GasModel
{
/// <summary>
/// Gas Type Contain Current Or Previous
/// </summary>
public string Columes { get; set; }
/// <summary>
///
/// </summary>
public ObservableCollection<GasHeaderName> GasHeaderName { get; set; }
}
public class GasHeaderName
{
/// <summary>
/// Gas Type Contain Current Or Previous
/// </summary>
public string GasName { get; set; }
/// <summary>
/// Gas Type Contain Current Or Previous
/// </summary>
public string GasTypeOfCurrent { get; set; }
/// <summary>
/// Gas Type Contain Current Or Previous
/// </summary>
public string GasTypeOfPrevious { get; set; }
}
public class FlowPressure
{
/// <summary>
/// FlowPressure Filed
/// </summary>
public string Flow { get; set; }
/// <summary>
/// FlowPressure Filed
/// </summary>
public string Pressure { get; set; }
/// <summary>
/// FlowPressure Filed
/// </summary>
public string Date { get; set; }
/// <summary>
/// FlowPressure Filed
/// </summary>
public string Time { get; set; }
/// <summary>
/// FlowPressure Filed
/// </summary>
public string MaxFlow { get; set; }
/// <summary>
/// FlowPressure Filed
/// </summary>
public string Gas { get; set; }
}
}