用WPF做报表控件(三)

表头

在上一节里面,我们已经知道,表头其实是一个Grid。那么有两个最需要解决的问题:

(1)表头列宽变化时,主体和表尾的列宽怎么跟着变化。

(2)如何初始化这个复杂的表头。

第一个问题其实并不难,在Grid每一列右侧,都加入一个GridSplitter,然后添加DragDelta和DragCompleted两个拖动事件即可。

gs.DragDelta += GridSplitter_DragDelta;
gs.DragCompleted += GridSplitter_DragCompleted;

private void GridSplitter_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
    ResizeWidth();
}

private void GridSplitter_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
    ResizeWidth();
}

在ResizeWidth方法里面,我们调整主体和表尾每一列的宽度。

private void ResizeWidth()
{
    if (init)
    {
        double total = 0;
        for (int i = 0; i < total_column; i++)
        {
            double width = HeadGrid.ColumnDefinitions[i].ActualWidth;
            total += width;

            BodyGrid.Columns[i].Width = new DataGridLength(width);
            foreach (UIElement obj in BottomPanel.Children)
            {
                StackPanel sp = (StackPanel)obj;
                (sp.Children[i] as TextBlock).Width = width;
            }
        }

        HeadGrid.Width = total + 18;
        BottomPanel.Width = total;
    }
}

对于第二个问题,不同的项目需求,使用的方法也会不一样。我使用了以下的结构体存储表头的结构:

public class HeaderClass
{
    public string n { get; set; }
    public List<HeaderClass> l { get; set; }
}

这类似于树的节点。可以用XML文件去初始化,也可以读入数据库。读入数据之后,扫描这个结构体,算出有多少行多少列,哪些列需要合并。最核心的三个方法如下:

public void InitHeader(HeaderClass hc)
{
    HeadGrid.Children.Clear();
    HeadGrid.ColumnDefinitions.Clear();
    HeadGrid.RowDefinitions.Clear();

    total_row = 0;
    total_column = 0;
    int layer = 1;
    GetRowColumn(hc, layer, ref total_row, ref total_column);

    for (int i = 0; i < total_row; i++)
    {
        HeadGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1) });
        HeadGrid.RowDefinitions.Add(new RowDefinition());
    }
    for (int i = 0; i < total_column; i++)
    {
        HeadGrid.ColumnDefinitions.Add(new ColumnDefinition());
    }
    HeadGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(20) });

    int row = 0;
    int col = 0;
    CreateHeader(hc, row, total_row, ref col);
}

private void GetRowColumn(HeaderClass hc, int layer, ref int row, ref int column)
{
    if (hc.l != null && hc.l.Count != 0)
    {
        layer++;
        if (layer > row)
        {
            row = layer;
        }

        foreach (HeaderClass hci in hc.l)
        {
            GetRowColumn(hci, layer, ref row, ref column);
        }
    }
    else
    {
        column++;
    }
}

private int CreateHeader(HeaderClass hc, int row, int total_row, ref int col)
{
    if (hc.l != null && hc.l.Count != 0)
    {
        row++;
        int my_col = col;
        int col_span = 0;
        foreach (HeaderClass hci in hc.l)
        {
            col_span += CreateHeader(hci, row, total_row, ref col);
        }
        AddHeader(row * 2 - 1, 1, my_col, col_span, hc.n);
        return col_span;
    }
    else
    {
        row++;
        AddHeader(row * 2 - 1, (total_row - row + 1) * 2 - 1, col, 1, hc.n);
        col++;
        return 1;
    }
}

猜你喜欢

转载自blog.csdn.net/lweiyue/article/details/82492116