質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • C#

    7089questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    1825questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C# WinformのDataGridViewで、FrozenをFalseにしても固定が解除出来ない

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 703

sheephuman

score 39

マウスホイールイベント使用時、カーソル移動よりも内部のスクロールが優先される仕様のため、それを抑制しようと考えました。
列を3つ追加済みのものとします。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp9
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            dataGridView1.MouseWheel += new MouseEventHandler(dataGridView1_MouseWheel);

        }

        private void dataGridView1_MouseWheel(object sender, MouseEventArgs e)
        {
            try
            {
                dataGridView1.MultiSelect = false;


                int wheel = e.Delta / 120;
        //マウスホイール時の上下


                int CurrentRow = dataGridView1.CurrentCell.RowIndex - wheel;

                int CurrentCell = dataGridView1.CurrentCell.ColumnIndex;

       //マウスホイール時に選択行を1ずつ変更
                dataGridView1.Rows[CurrentRow].Cells[CurrentCell].Selected = true;


                //現在の選択行が10以上のとき固定を解除
                if (10 < CurrentRow)
                {
                    dataGridView1.Rows[10].Frozen = false;

                    dataGridView1.FirstDisplayedScrollingColumnIndex = 10;
                       //10行目から表示
                }
            }

            catch (Exception ex)
            {
                //   MessageBox.Show(ex.Message, dataGridView1.RowCount.ToString());
                Console.WriteLine(ex);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {         
            int CountVal = 0;

            for (int i=0; i < 30; i++)
            {
                dataGridView1.Rows.Add();
                for (int C = 0; C < 3; C++)
                {
                    dataGridView1.Rows[i].Cells[C].Value = CountVal;
                        CountVal++;
                }


            }
            dataGridView1.Rows[10].Frozen = true;
        }
    }
}


実行結果
実行結果
 
 
通常であれば、このようにして固定が解除された状態では、スクロールも初期状態に戻るはずですが、固定された状態のままです。どのようにすれば解除できるのか教えてください。

 試したこと
マウスホイール動作を無効化したい

を参考にしましたが、スクロール動作は無効化出来たものの、既存のマウスホイールイベントが上書きされたために、マウスホイール時のカーソル移動が無効化されました。

更に試したこと

protected override void OnMouseWheel(MouseEventArgs e)
        {       
            HandledMouseEventArgs wEventArgs = e as HandledMouseEventArgs;
            wEventArgs.Handled = true;
           int Wheel = e.Delta / 120;

            CurrentCell = CurrentRow.Cells[Wheel];
        }


try Catchで囲んでも、僅かにカーソルが動いただけで配列の境界外errorになります。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2018/01/03 21:23

    Wheel の値を確かめてください。Delta はどれだけホイールが回ったかというものなので添え字には向きません。

    キャンセル

  • sheephuman

    2018/01/03 21:26

    常に1か-1になるように、自分の環境で調整してます。

    キャンセル

  • Zuishin

    2018/01/03 21:28

    -1 は範囲外です。

    キャンセル

回答 3

checkベストアンサー

0

DataGridView を継承しても良ければ OnMouseWheel で e.Handled を true にすることでホイールのデフォルト動作を無効にできます。
そこで同時にカーソル移動すればいいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/03 20:39

    オーバーライドは試したんですが、カーソル移動の方法が分かりませんでした。よろしければ、コード例の記載をお願いします。

    キャンセル

  • 2018/01/03 20:40

    CurrentRow です。

    キャンセル

  • 2018/01/03 20:43

    CurrentCell でした。
    https://dobon.net/vb/dotnet/datagridview/currentcell.html

    キャンセル

  • 2018/01/03 20:49

    すみません。OverrideしたOnMouseWheelメソッドで入れると「読み取り専用であるため、割り当てることが出来ません」と表示されます。
    CurrentRow、CurrentCellで同様の結果です。

    キャンセル

  • 2018/01/03 20:50

    https://msdn.microsoft.com/ja-jp/library/system.windows.forms.datagridview.currentcell(v=vs.110).aspx
    CurrentCell は読み書きできます。

    CurrentRow は読み取り専用です。

    キャンセル

  • 2018/01/03 21:37

    ちょっと大変でしたが実装出来ました。ありがとうございました。

    キャンセル

0

OnMouseWheelをOverRideしたときの実装

 {
 protected override void OnMouseWheel(MouseEventArgs e)
        {
            try
            {
                HandledMouseEventArgs wEventArgs = e as HandledMouseEventArgs;
                wEventArgs.Handled = true;

                  int Wheel = e.Delta / 120;
                CurrentCell = Rows[CurrentCell.RowIndex -Wheel].Cells[0];
 catch
            { }
       }


とてもスムーズに動きました。助かりました。 
随分と手間どってしまいました。 

追記 スクロールイベントで調整したら意外と上手く行きました。

   private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
        {
            int CurrentRow = dataGridView1.CurrentCell.RowIndex;

            Text = CurrentRow.ToString();
            if (dataGridView1.FirstDisplayedScrollingRowIndex < 10)
            {

                if (CurrentRow < 10)
                {
                    dataGridView1.FirstDisplayedScrollingRowIndex = 0;
                }
            }
            else if(dataGridView1.FirstDisplayedScrollingRowIndex >10)
            {
                if(CurrentRow > 10)
                {

                    dataGridView1.FirstDisplayedScrollingRowIndex = CurrentRow-3;

                }


            }
        }

結局、このような感じで調整しました。もっと良い方法があればお願いします。挙動が微妙です。

   if (3 < CurrentRow && wheel == -1) //ホイール下移動時
       {
       dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.CurrentCell.RowIndex-3 ;
     }

  else if(wheel == 1)  //ホイール上移動時
      {
  dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.CurrentCell.RowIndex-6;
       }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/03 20:40

    後ほど自己解決にしたいと思います。

    キャンセル

0

現在はこのようなコードにしています。

   /// <summary>
        /// dataGridviewのスクロール抑止
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseWheel(MouseEventArgs e)
        {


            int Wheel = e.Delta / 120;
            try
            {
                HandledMouseEventArgs wEventArgs = e as HandledMouseEventArgs;
                wEventArgs.Handled = true;


                //例外回避のための条件指定
                if (CurrentCell.RowIndex - Wheel < RowCount && CurrentCell.RowIndex - Wheel > -1)
                {


                    CurrentCell = Rows[CurrentCell.RowIndex - Wheel].Cells[CurrentCell.ColumnIndex];

                }
            }
            catch
            {  

                //例外は出ない }
            }
        }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    DatagridView再表示について

        Private Sub SubPurchaseForm_FormClosed(sender As Object, e As FormClosedEventArgs) Han

  • 解決済

    C# DataGridViewのCheckBoxについて

    前提・実現したいこと Visual Studio2013 にて開発の勉強をしています。 DataGridViewにてCheckBoxのOnOFFの設定をしたいのですがど

  • 解決済

    DataGridViewで最終行だけ入力可にする方法

    いつもお世話になっております。 表題の件なのですが 最終行だけ常に入力可能にしておく方法はありますでしょうか? イベントも Private Sub gv_RowsAdded

  • 解決済

    C#

    C#について解決いたしました。本当に助かりました。またどうぞ宜しくお願いいたします。

  • 解決済

    C# DatagridViewの使い方

    C# DataGridViewについて 1列目の1行目にA、2行目にB、3行目にCと表示したくて下記のようにコーディングしました。 namespace WindowsF

  • 解決済

    DataGridViewのイベント

    Form1の画面にDataGridViewを貼りつけ、DataGridViewのカラムを3つ追加します。 カラム1のColumn TypeはDataGridView TextB

  • 解決済

    DataGridViewのComboBoxについて

    DataGridViewのColumn1がComboBoxのカラムだとします。 DataTable dt = new DataTable(); dt.C

  • 解決済

    グリッドのチェックボックス制御

    VisualStdlo2015でシステムを開発しています。 画面のグリッドにデータを表示させ、一番左の列にチェックボックスを配置しました。(数量の列も配置) 起動後、チェックボック

同じタグがついた質問を見る

  • C#

    7089questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    1825questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。