根据行数,列数自动创建表格,使用WPF中的Grid很容易实现,并且容易实现单元格的合并拆分。主要需要解决两个问题:
单元格的定位,那一行,那一列,占几行,占几列单元格的边框
行,列,占行,占列
该问题比较容易解决,Grid分行,分列后,添加的控件可以使用Grid.Row,Grid.Column,Grid.RowSpan,Grid.ColumnSpan解决。
单元格边框
每一个单元格使用一个Border,控制上下左右的边框达到显示单元格边框,具体如下图:
需要注意的是,最终表格的每个单元格中是包含其它控件的,如textbox,该控件的最小高度若是22,则对于首行来说,其高度应该是22+2=24,对于其它行来说,高度应该是22+1=23,即需要包含边框,同理,列宽有时也需要注意,实践中发现列宽基本不影响,所以可不调节。
最后实现的图示:
相关代码:
后台代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnAdd_Click(
object sender, RoutedEventArgs e)
{
var rowct =
int.Parse(tbRow.Text);
var colct =
int.Parse(tbCol.Text);
InitRowDefAndColDef(gd, rowct, colct);
InitGridCell(gd);
}
private void InitRowDefAndColDef(Grid grid,
int rowct,
int colct)
{
for (
int i =
0; i < rowct; i++)
{
var rowdef =
new RowDefinition {MinHeight =
22 + (i ==
0 ?
2 :
1)};
grid.RowDefinitions.Add(rowdef);
}
for (
int i =
0; i < colct; i++)
{
grid.ColumnDefinitions.Add(
new ColumnDefinition {Width =
new GridLength(
1, GridUnitType.Star)});
}
}
private void InitGridCell(Grid grid)
{
var rowct = grid.RowDefinitions.Count;
var colct = grid.ColumnDefinitions.Count;
for(
int i=
0;i<rowct;i++)
for (
int j =
0; j < colct; j++)
{
var border =
new Border();
border.SetValue(Grid.RowProperty,i);
border.SetValue(Grid.ColumnProperty, j);
border.Style =
this.FindResource(
"cellStyle")
as Style;
grid.Children.Add(border);
}
}
}
前台代码:
<Window x:Class=
"testxx.MainWindow"
xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x=
"http://schemas.microsoft.com/winfx/2006/xaml"
Title=
"MainWindow" Height=
"350" Width=
"525">
<Window.Resources>
<
Style x:Key=
"cellStyle" TargetType=
"Border">
<
Setter Property=
"BorderBrush" Value=
"Black"></
Setter>
<
Setter Property=
"BorderThickness" Value=
"0,0,1,1"></
Setter>
<
Style.Triggers>
<
Trigger Property=
"Grid.Row" Value=
"0">
<
Setter Property=
"BorderThickness" Value=
"0,1,1,1"></
Setter>
</
Trigger>
<
Trigger Property=
"Grid.Column" Value=
"0">
<
Setter Property=
"BorderThickness" Value=
"1,0,1,1"></
Setter>
</
Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<
Condition Property=
"Grid.Row" Value=
"0"></
Condition>
<
Condition Property=
"Grid.Column" Value=
"0"></
Condition>
</MultiTrigger.Conditions>
<
Setter Property=
"BorderThickness" Value=
"1,1,1,1"></
Setter>
</MultiTrigger>
</
Style.Triggers>
</
Style>
</Window.Resources>
<
Grid>
<
Grid.ColumnDefinitions>
<ColumnDefinition Width=
"411*"/>
<ColumnDefinition Width=
"106*"/>
</
Grid.ColumnDefinitions>
<
Grid Margin=
"10" Name=
"gd" Grid.
Column=
"0" HorizontalAlignment=
"Stretch" VerticalAlignment=
"Center"/>
<
Button x:Name=
"btnAdd" Content=
"Add" HorizontalAlignment=
"Left" Margin=
"20.884,133,0,0" VerticalAlignment=
"Top" Width=
"75" Click=
"btnAdd_Click" Grid.
Column=
"1"/>
<
TextBox x:Name=
"tbRow" HorizontalAlignment=
"Left" Height=
"23" Margin=
"20.884,41,0,0" TextWrapping=
"Wrap" Text=
"4" VerticalAlignment=
"Top" Width=
"75" Grid.
Column=
"1"/>
<
TextBox x:Name=
"tbCol" HorizontalAlignment=
"Left" Height=
"23" Margin=
"20.884,83,0,0" TextWrapping=
"Wrap" Text=
"5" VerticalAlignment=
"Top" Width=
"75" Grid.
Column=
"1"/>
</
Grid>
</Window>
问题
画出来的线有时线宽不是1,稍微调整表格高度或宽度又会正常,如下图正常显示的,可以明显对比出来,实际边框宽度均为1。 貌似和什么浮点绘图有关系,解决其实简单,设置外层控件的SnapsToDevicePixels = True即可(不要使用OverrideMetadata,实验结果发现这样结果不对,可以放在style中或构造函数中)。
其它
这里给出了表格的自动生成方式,对于表格的拆分,合并,拖动选中(需要计算选中的单元格集,必须是一个长方块),需要通过设置Border的RowSpan及ColSpan解决。