為了要在C1FlexGrid中做出如下Header Cell合併的效果,煞費苦心...

簡單來說,這類的合併效果必須繼承C1FlexGrid再做一顆自訂元件,並Override GetMergeCell這個函數,判斷傳入的Row/Col數是否屬於合併範圍決定傳回值。而GetMergeCell在UI重畫過程中會被高速連續呼叫,函數中的邏輯要盡可能簡化,並避免掉所有不必要的運算,否則就等著在執行階段看你的CPU破表吧!

public class CustC1FlexGrid : C1FlexGrid
{
    //用來儲存合併範圍Index的物件
    private class CellRangeIndex 
    {
        public int StartRow, StartCol, EndRow, EndCol;
        public CellRangeIndex(
            int startRow, int startCol, 
            int endRow, int endCol)
        {
            StartRow = startRow;
            EndRow = endRow;
            StartCol = startCol;
            EndCol = endCol;
        }
    }
 
    #region Constructor & Dispose(略)
    #endregion
    
    //儲存合併設定
    CellRangeIndex[,] mergeMapping = null;
    //是否需要處理合併
    bool needMerging = false;
    //指定哪幾個Cell合併成一個
    public void MergeCells(int startRowIdx, int startColIdx, 
        int endRowIdx, int endColIdx) 
    {
        needMerging = true;
        CellRangeIndex cri =
            new CellRangeIndex(startRowIdx, startColIdx,
            endRowIdx, endColIdx);
        for (int i=startRowIdx; i<=endRowIdx; i++) 
            for (int j=startColIdx; j<=endColIdx; j++)
                mergeMapping[i, j]=cri;
    }
    //Header的Row數
    private int HEADER_ROW_COUNT = 2;
    //設定必要的合併用參數及變數
    public void InitMergeSetting() 
    {
        this.AllowMerging = AllowMergingEnum.FixedOnly;
        for (int r = 0; r < HEADER_ROW_COUNT; r++)
            Rows[r].AllowMerging = true;
        for (int c = 0; c < Cols.Count; c++) 
            Cols[c].AllowMerging = true;
        mergeMapping = 
            new CellRangeIndex[HEADER_ROW_COUNT, Cols.Count];
    }
    //自訂欄位合併的邏輯
    public override CellRange GetMergedRange
(int row, int col, bool clip)
    {
        if (needMerging && 
            row < HEADER_ROW_COUNT && 
            mergeMapping[row, col]!=null)
        {
            CellRangeIndex cri = mergeMapping[row, col];
            return base.GetCellRange(
                cri.StartRow, cri.StartCol,
                cri.EndRow, cri.EndCol);
        }
        return base.GetCellRange(row, col);
    }
 
    #region Component Designer generated code
    #endregion
}

看似簡單的一個需求,不能用設定解決而要另寫繼承元件,讓整件事變得複雜,所幸元件寫好後,呼叫端看來還算簡單。再補充一點,你必須在要合併的兩個Cell中都指定同樣的值,兩個Cell才會合併在一起。

private void Form1_Load(object sender, System.EventArgs e)
{
    c1.Rows.Count=10;
    c1.Cols.Count=6;
    c1.InitMergeSetting();
    c1.MergeCells(0,1,0,2);
    c1.MergeCells(0,3,0,4);
    c1.MergeCells(0,0,1,0);
    c1.MergeCells(0,5,1,5);
    c1[0, 0]=c1[1, 0]="Name";
    c1[0, 1]=c1[0, 2]="PC";
    c1[1, 1]="CPU";
    c1[1, 2]="RAM";
    c1[0, 3]=c1[0, 4]="NB";
    c1[1, 3]="CPU";
    c1[1, 4]="RAM";
    c1[0, 5]=c1[1, 5]="Remark";
 
}

Comments

# by 111

For More information http://helpcentral.componentone.com/nethelp/c1flexgrid/

Post a comment