5.20241.9

グリッド:カスタムセル結合

デフォルトでは、FlexGridは、セルコンテンツに基づいてセルに結合を適用します。ただし、別の方法を使用して結合を行いたい場合もあります。

それには、wijmo.grid.MergeManagerクラスを拡張するクラスを定義し、そのタイプのオブジェクトをグリッドのmergeManagerプロパティに割り当てます。

次の例では、この方法でTV番組表のようなグリッドを作成しています。

カスタム結合マネージャーによって複数の行と複数の列の両方にまたがる結合範囲が作成されていることがわかります。デフォルトの結合マネージャーでは、このようなことは行われません。

import * as wjGrid from '@mescius/wijmo.grid';
import * as wjCore from '@mescius/wijmo';

export class CustomMergeManager extends wjGrid.MergeManager {
    constructor(flexGrid) {
        super(flexGrid);
    }
    getMergedRange(panel, r, c, clip = true) {
        // create basic cell range
        var rg = new wjGrid.CellRange(r, c);
        // expand left/right
        for (var i = rg.col; i < panel.columns.length - 1; i++) {
            if (panel.getCellData(rg.row, i, true) != panel.getCellData(rg.row, i + 1, true))
                break;
            rg.col2 = i + 1;
        }
        for (var i = rg.col; i > 0; i--) {
            if (panel.getCellData(rg.row, i, true) != panel.getCellData(rg.row, i - 1, true))
                break;
            rg.col = i - 1;
        }
        // expand up/down
        for (var i = rg.row; i < panel.rows.length - 1; i++) {
            if (panel.getCellData(i, rg.col, true) != panel.getCellData(i + 1, rg.col, true))
                break;
            rg.row2 = i + 1;
        }
        for (var i = rg.row; i > 0; i--) {
            if (panel.getCellData(i, rg.col, true) != panel.getCellData(i - 1, rg.col, true))
                break;
            rg.row = i - 1;
        }
        // done
        return rg;
    }
}
function setData(p, r, cells) {
    if (p.cellType == wjGrid.CellType.Cell) {
        p.grid.rowHeaders.setCellData(r, 0, cells[0]);
    }
    for (var i = 1; i < cells.length; i++) {
        p.setCellData(r, i - 1, cells[i]);
    }
}
function centerCell(s, e) {
    if (e.cell.children.length == 0) {
        e.cell.innerHTML = '<div>' + e.cell.innerHTML + '</div>';
        wjCore.setCss(e.cell, {
            display: 'table',
            tableLayout: 'fixed'
        });
        wjCore.setCss(e.cell.children[0], {
            display: 'table-cell',
            textAlign: 'center',
            verticalAlign: 'middle'
        });
    }
}

function init() {
    // 5行、7列の非連結グリッドを作成します
    var theGrid = new wjGrid.FlexGrid('#theGrid');
    while (theGrid.columns.length < 7) {
        theGrid.columns.push(new wjGrid.Column());
    }
    while (theGrid.rows.length < 5) {
        theGrid.rows.push(new wjGrid.Row());
    }
    // グリッドを設定します
    theGrid.mergeManager = new CustomMergeManager(theGrid);
    theGrid.formatItem.addHandler(centerCell);
    theGrid.rowHeaders.columns[0].width = 80;
    theGrid.rows.defaultSize = 40;
    theGrid.showAlternatingRows = false;
    theGrid.isReadOnly = true;
    // グリッドに入力します
    setData(theGrid.columnHeaders, 0, ',月,火,水,木,金,土,日'.split(','));
    setData(theGrid.cells, 0, '12:00,昼のニュース,昼のニュース,昼のニュース,スポーツ,天気予報,未定,未定'.split(','));
    setData(theGrid.cells, 1, '13:00,ワイドショー,ワイドショー,アニメ,サッカー,経済ニュース,未定,未定'.split(','));
    setData(theGrid.cells, 2, '14:00,ワイドショー,ワイドショー,アニメ,サッカー,ドラマ,未定,未定'.split(','));
    setData(theGrid.cells, 3, '15:00,ニュース,ニュース,ニュース,ニュース,ニュース,未定,未定'.split(','));
    setData(theGrid.cells, 4, '16:00,ニュース,ニュース,ニュース,ニュース,ニュース,未定,未定'.split(','));
}