UltraGrid のヘッダーのチェックボックスは既定で、グリッドのフィルター状態にかかわらずすべての行のチェック状態を切り替えます。BeforeHeaderCheckStateChanged イベント内で Row.IsFilteredOut を判定することで、フィルターで絞り込まれている行のみをチェック・アンチェックする動作に変更できます。

UltraGrid の設定

まず、ヘッダーのチェックボックスを表示し、既定の同期処理を無効にして自前で制御できるようにします。CheckBoxSynchronizationNone に設定することで、行のチェック状態の同期を BeforeHeaderCheckStateChanged イベント側で行えるようになります。

private void ultraGrid1_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
    var band = e.Layout.Bands[0];

    e.Layout.Override.FilterUIType = FilterUIType.FilterRow;

    var isCheckedCol = band.Columns["IsChecked"];
    isCheckedCol.Style = Infragistics.Win.UltraWinGrid.ColumnStyle.CheckBox;
    isCheckedCol.Header.CheckBoxSynchronization = HeaderCheckBoxSynchronization.None;
    isCheckedCol.Header.CheckBoxVisibility = HeaderCheckBoxVisibility.Always;
}

BeforeHeaderCheckStateChanged の処理

BeforeHeaderCheckStateChanged イベントでは、ユーザーがヘッダーのチェックボックスをクリックしたときの新しいチェック状態を、row.IsFilteredOutfalse の行(フィルターで絞り込まれている行)だけを対象に判定・更新します。フィルターで非表示になっている行は判定にも更新にも含めません。最後に SetHeaderCheckedState を呼び出し、ヘッダーのチェックボックスの表示状態を実際の行の状態に同期させます。

bool isProgrammaticallyUpdatingHeaderCheckState = false;

private void ultraGrid1_BeforeHeaderCheckStateChanged(object sender, BeforeHeaderCheckStateChangedEventArgs e)
{
    var lastElementEntered = ultraGrid1.DisplayLayout.UIElement.LastElementEntered;

    if (!isProgrammaticallyUpdatingHeaderCheckState &&
        lastElementEntered?.Parent is HeaderCheckBoxUIElement)
    {
        // フィルターで非表示になっていない全行がチェック済みかどうかを判定する
        // (フィルタリングされた行は判定から除外する)
        var allVisibleRowsChecked = ultraGrid1.Rows.All(row =>
            row.IsFilteredOut ||
            (row.Cells["IsChecked"].Value is bool value && value));

        var newCheckedValue = !allVisibleRowsChecked;

        // フィルタリングされていない行のチェック状態のみを一括更新する
        foreach (var row in ultraGrid1.Rows)
        {
            if (!row.IsFilteredOut)
            {
                row.Cells["IsChecked"].Value = newCheckedValue;
            }
        }

        this.BeginInvoke(new Action(() =>
        {
            isProgrammaticallyUpdatingHeaderCheckState = true;

            ultraGrid1.DisplayLayout.Bands[0]
                .Columns["IsChecked"]
                .SetHeaderCheckedState(ultraGrid1.Rows, newCheckedValue);

            isProgrammaticallyUpdatingHeaderCheckState = false;
        }));
    }

    ultraGrid1.UpdateData();
}

実行結果

グリッドをフィルターで絞り込んだ状態でヘッダーのチェックボックスをクリックすると、フィルターで表示されている行のみがチェック・アンチェックされ、フィルターで非表示になっている行のチェック状態は変化しないことを確認できます。

フィルターで絞り込んだ状態でヘッダーのチェックボックスをクリックする

フィルターを解除する

Tagged:

製品について

Ultimate UI for Windows Forms