インフラジスティックス・ジャパン株式会社のBlog

インフラジスティックス・ジャパン株式会社のチームメンバーが技術トレンド、製品Tips、サポート情報からライセンス、日々の業務から感じることなど、さまざまなトピックについてお伝えするBlogです。

みんな大好きExcelライク! ~UltraWinGrid~

今更WindowsFormsですか?と思われる方もいらっしゃるかと思いますが、WinFormsで業務アプリケーション開発が行われることはまだまだ多く、実際Windows Forms向けコントロールに関するお問い合わせをかなり多く頂いております。その中でも、「エクセルのような挙動を頼む」、「入力中でも十字キーでフォーカス移動したい」などなどグリッドコントロールのカーソル移動に関するお問い合わせは特に多くいただいております。

image

このポストではUltraWinGridのカーソル移動関連の制御方法をご紹介します。

解説用サンプルソース

private void ultraGrid1_KeyDown(object sender, KeyEventArgs e)
{
    if (ultraGrid1.ActiveCell != null)
    {
        //編集中のキーダウンかどうかの判定
        if (ultraGrid1.ActiveCell.IsInEditMode)
        {
            //gridActionの初期設定(Undoを初期値とする)
            Infragistics.Win.UltraWinGrid.UltraGridAction gridAction =  Infragistics.Win.UltraWinGrid.UltraGridAction.Undo;


            switch (e.KeyCode)
            {
                case Keys.Down:
                    //下のセルに移動
                    gridAction = Infragistics.Win.UltraWinGrid.UltraGridAction.BelowCell;
                    break;

                case Keys.Up:
                    //上のセルに移動
                    gridAction = Infragistics.Win.UltraWinGrid.UltraGridAction.AboveCell;
                    break;

                case Keys.Right:
                    //編集中のカーソルが端まで行った時にセル移動させたい場合は以下の判定
                    if (ultraGrid1.ActiveCell.EditorResolved.GetType() == typeof(Infragistics.Win.EditorWithText))
                    {
                        //Editorである場合
                        if (ultraGrid1.ActiveCell.EditorResolved.TextLength
                            == ultraGrid1.ActiveCell.EditorResolved.SelectionStart
                            + ultraGrid1.ActiveCell.EditorResolved.SelectionLength)
                        {
                            //右端まで行った場合
                            gridAction = Infragistics.Win.UltraWinGrid.UltraGridAction.NextCell;
                        }
                    }
                    break;

                case Keys.Left:
                    //編集中のカーソルが端まで行った時にセル移動させたい場合は以下の判定
                    if (ultraGrid1.ActiveCell.EditorResolved.GetType() == typeof(Infragistics.Win.EditorWithText))
                    {
                        //Editorである場合
                        if (ultraGrid1.ActiveCell.EditorResolved.SelectionStart == 0)
                        {
                            //左端にカーソルがある場合
                            gridAction = Infragistics.Win.UltraWinGrid.UltraGridAction.PrevCell;
                        }
                    }
                    break;


                case Keys.Enter:
                    if (e.Shift)
                    {
                        //上のセルに移動(Shiftあり時)
                        gridAction = Infragistics.Win.UltraWinGrid.UltraGridAction.AboveCell;
                    }
                    else
                    {
                        //下のセルに移動(Shift無し時)
                        gridAction = Infragistics.Win.UltraWinGrid.UltraGridAction.BelowCell;
                    }
                    break;

            }

            //gridActionに変更があった場合は移動する
            if (gridAction != Infragistics.Win.UltraWinGrid.UltraGridAction.Undo)
            {
                //編集モードから抜ける
                ultraGrid1.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.ExitEditMode);
                //次のセルへ移動
                ultraGrid1.PerformAction(gridAction);
                
                //Handled状態にし、本来のキー操作を無効にする
                e.Handled = true;
            }
        }
        else
        {
            //編集中でない場合もEnterKey移動はハンドリングする
            if (e.KeyCode == Keys.Enter)
            {
                if (e.Shift)
                {
                    //上のセルに移動(Shiftあり時)
                    ultraGrid1.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.AboveCell);
                }
                else
                {
                    //下のセルに移動(Shift無し時)
                    ultraGrid1.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.BelowCell);
                }
            }
        }
    }
}

private void ultraGrid1_AfterEnterEditMode(object sender, EventArgs e)
{
    //テキストかどうか判定
    if (ultraGrid1.ActiveCell.EditorResolved.GetType() == typeof(Infragistics.Win.EditorWithText))
    {
        //最後にカーソル設定
        ultraGrid1.ActiveCell.EditorResolved.SelectionStart = ultraGrid1.ActiveCell.EditorResolved.TextLength;
    }
}

private void ultraGrid1_AfterCellActivate(object sender, EventArgs e)
{
    //ActiveCell変更後は常に編集モードへ遷移する場合は以下のコード
    ultraGrid1.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.EnterEditMode);
}

UltraWinGridの標準の挙動と制御方法について解説していきます。

■編集モード
UltraWinGridの各セルは、常に編集モードか表示モード(非編集モード)に属します。標準動作では編集モード中は矢印キーでは他のセルに移動することはできず、Tabキーで次セルへ移動し、Enterキーでセル移動無しで編集モードから抜けます。また、編集モードでない場合は十字キーでセル移動を行うことができます。

編集モードに入るトリガーについては、エクセルと同様にF2キーを押下すると編集モードに入る事ができますが、プロパティ設定でセルクリック時に編集モードへ入れるかどうかを設定する事ができます。※セルの複数選択をさせたい場合はこの設定を行わないで下さい!編集モード中はセルの複数選択はできません。

//Cellクリック時は編集モードには入る
this.ultraGrid1.DisplayLayout.Override.CellClickAction = Infragistics.Win.UltraWinGrid.CellClickAction.Edit;

■十字キー移動
上記のとおり、標準動作では編集モード中には矢印キーでセル移動させることができませんが、KeyDownイベントをハンドリングすることでそれを可能にすることができます。

コードの13行目のSwitch Case文でキーコードを判定し十字キーとEnterキーの場合にそれぞれ適切な方向にカーソル移動させる処理を書いています。実際にカーソル移動を行っているのはコード74行目の”ultraGrid1.PerformAction(gridAction)”の箇所です。このPerformActionというメソッドはこのサンプルコード内でも多用していますが、グリッドに指定したアクションを行わせる大変便利なもので、行わせるこの出来るアクションが多数用意されています。(Undo,Redo,Copy,Cut,etc…)

十字キー押下時の処理の中でも、Keys.RightとLeftの場合は少し判定文をかませています。セルのタイプがEditorだった場合は、キャレットの位置と文字の選択状況を考慮しキャレットが端まで行った場合に次のセルに映るという事を行っています。

■常に編集モード
十字キー移動を有効にしても、セルが移動した後で編集モードに入っていなければ再度編集モードへ入れる手間が増えてしまいます。コード110行目では、セルの移動(Activationの変化)があった時に、PerformActionメソッドを用いて移動先のセルで編集モードに入れています。

■キャレット操作
セルが編集モードに遷移した際、セル内の文字を全選択させたいのか、それとも文字の先頭か末尾にキャレットを設定させたいのか、ケースバイケースだと思います。コード110行目では、セルが編集モードへ入った直後のイベントAfterEnterEditModeをハンドリングして、エクセルの標準動作でもある文字の末尾にキャレットを設定するということを行っています。

もしテキストを全選択させたい場合は、上記サンプルコードの様にEditorResolvedのSelectionStartとTextLengthの設定を行うことでも実装できますが、以下の様にSelectAllメソッド一つで実装することができます。

//セル内の文字の全選択
ultraGrid1.ActiveCell.EditorResolved.SelectAll();

上記のサンプルコードと解説を参考に、それぞれの要件にあった挙動を実装してみてください!もし分からない点があればお気軽にサポート窓口までお問い合わせ下さい。

今回のサンプルはこちらから 

UltraWinGrid を含む NetAdvantage for WindowsForms は機能制限のない無料トライアルをご利用頂けます。無料トライアルにも有償製品版と同じようにサポートサービスをご利用頂けます。利用方法に不明点がございましたら是非弊社カスタマーサポートまでお問い合わせ下さい。

NetAdvantage トライアル版ダウンロード

Windows Formsコントロール - Infragistics Ultimate UI for Windows Forms