C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: C# 複数のDataGridViewを一度に操作


(過去ログ 136 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■80276 / inTopicNo.1)  C# 複数のDataGridViewを一度に操作
  
□投稿者/ ごう (4回)-(2016/06/26(Sun) 19:39:11)

分類:[.NET 全般] 

OS:Windows7
開発環境:Visual Studio 2010 Professional

3つのDataGridViewを水平方向に並べ、
データ(行)が追加されるときにはすべてのDataGridViewに対して同時に行追加を行おうとしています。

併せて以下の機能を実装予定です。
a. 行追加は毎回グリッドの最下行に対して行う。
   行追加されたら、追加した行全体を選択状態にする。
   すべてのDataGridViewに対して適用する。

b. 行クリックを行ったら、クリックされた行全体を選択状態にする。
   すべてのDataGridViewに対して適用する。

c. 上下キーを使って選択行が変更になったら、
   すべてのDataGridViewに対してクリックされた行全体を選択状態にする。

d. スクロールバーコントロールを動かしたら、すべてのDataGridViewのスクロールを同時に行う。

現在、行の追加と上下キーを使って選択行を変更した場合の処理ができず困っております。
現状では、2行目を追加するときプログラムを動かすとエラーになり落ちてしまいます。
(エラーは、「'System.StackOverflowException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。」と出ました。)
現象を再現させるためのコードを書いてみました。(ここではDataGridViewを1つにしています)

SelectionChangedイベントの使い方が、間違っているのではないか?と思っているのですが
どのように実装すればよいかわからないため、ご教示お願いいたします。



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

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private int cnt;

        public Form1()
        {
            InitializeComponent();

            dataGridView1.Columns.Add("col1", "col1");
            dataGridView1.Columns.Add("col2", "col2");

            dataGridView2.Columns.Add("col1", "col1");
            dataGridView2.Columns.Add("col2", "col2");

            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dataGridView2.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

            // 縦スクロールバーの初期位置、最小値、最大値を設定
            vScrollBar1.Value = 0;
            vScrollBar1.Minimum = 0;
            vScrollBar1.Maximum = dataGridView1.RowCount - 1;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {            
            dataGridView1.Rows.Add();
            dataGridView2.Rows.Add();

            dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0].Value = cnt;
            dataGridView2.Rows[dataGridView2.Rows.Count - 1].Cells[0].Value = cnt;
            cnt++;

            // 最新行選択(レコードセレクタ)
            dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0];
            dataGridView2.CurrentCell = dataGridView2.Rows[dataGridView2.Rows.Count - 1].Cells[0]; 

            // 最新行選択
            dataGridView1.Rows[dataGridView1.Rows.Count - 1].Selected = true;
            dataGridView2.Rows[dataGridView2.Rows.Count - 1].Selected = true;

            dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count - 1;
            dataGridView2.FirstDisplayedScrollingRowIndex = dataGridView2.Rows.Count - 1;

            vScrollBar1.Minimum = 0;
            vScrollBar1.Maximum = dataGridView1.RowCount - 1;
            vScrollBar1.Value = vScrollBar1.Maximum;
        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            dataGridView2.CurrentCell = dataGridView2.Rows[e.RowIndex].Cells[0]; 
            dataGridView2.Rows[e.RowIndex].Selected = true;
        }

        private void dataGridView2_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[0];
            dataGridView1.Rows[e.RowIndex].Selected = true;
        }

        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            dataGridView1.FirstDisplayedScrollingRowIndex = e.NewValue;
            dataGridView2.FirstDisplayedScrollingRowIndex = e.NewValue;
        }

        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            DataGridViewCell cell = dgv.CurrentCell;

            if ((dataGridView1.Rows.Count > 0) && (dataGridView2.Rows.Count > 0))
            {
                dataGridView1.CurrentCell = dataGridView1.Rows[cell.RowIndex].Cells[0];
                dataGridView1.Rows[cell.RowIndex].Selected = true;
                //dataGridView1.FirstDisplayedScrollingRowIndex = cell.RowIndex;

                dataGridView2.CurrentCell = dataGridView2.Rows[cell.RowIndex].Cells[0];
                dataGridView2.Rows[cell.RowIndex].Selected = true;
                //dataGridView2.FirstDisplayedScrollingRowIndex = cell.RowIndex;
            }
        }
    }
}

引用返信 編集キー/
■80277 / inTopicNo.2)  Re[1]: C# 複数のDataGridViewを一度に操作
□投稿者/ shu (889回)-(2016/06/27(Mon) 07:49:42)
No80276 (ごう さん) に返信

> 現在、行の追加と上下キーを使って選択行を変更した場合の処理ができず困っております。
> 現状では、2行目を追加するときプログラムを動かすとエラーになり落ちてしまいます。
> (エラーは、「'System.StackOverflowException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。」と出ました。)
> 現象を再現させるためのコードを書いてみました。(ここではDataGridViewを1つにしています)

 
>         private void dataGridView1_SelectionChanged(object sender, EventArgs e)
>         {
>             DataGridView dgv = sender as DataGridView;
>             DataGridViewCell cell = dgv.CurrentCell;
> 
>             if ((dataGridView1.Rows.Count > 0) && (dataGridView2.Rows.Count > 0))
>             {
>                 dataGridView1.CurrentCell = dataGridView1.Rows[cell.RowIndex].Cells[0];
ここと

>                 dataGridView1.Rows[cell.RowIndex].Selected = true;
>                 //dataGridView1.FirstDisplayedScrollingRowIndex = cell.RowIndex;
> 
>                 dataGridView2.CurrentCell = dataGridView2.Rows[cell.RowIndex].Cells[0];
ここで

>                 dataGridView2.Rows[cell.RowIndex].Selected = true;
>                 //dataGridView2.FirstDisplayedScrollingRowIndex = cell.RowIndex;
>             }
>         }
>     }
> }
> 
選択状態を変更しているのでdataGridView1_SelectionChangedが再度呼ばれる事になり
提示の例外が発生しているものと考えられます。

private bool flg = false;

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    if (flg) return;
    flg = true;
    < ここで処理を行う >
    flg = false;
}


このようにすればSelectionChangedが繰り返し発生することがなくなります。
ただしCurrentCell選択時にSelectionChangedにおけるなんらかの処理を行いたい場合は
別途実行する必要があります。

引用返信 編集キー/
■80302 / inTopicNo.3)  Re[2]: C# 複数のDataGridViewを一度に操作
□投稿者/ ごう (5回)-(2016/07/02(Sat) 09:41:28)
shuさん

ご回答ありがとうございます。
SelectionChangedに原因があったようなので
フラグを使って対応することで解決しました。

> このようにすればSelectionChangedが繰り返し発生することがなくなります。
> ただしCurrentCell選択時にSelectionChangedにおけるなんらかの処理を行いたい場合は
> 別途実行する必要があります。
>

a.の「行追加されたら、追加した行全体を選択状態にする。」が現在できておりませんので
当方で引き続き調査します。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -