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

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

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

Re[3]: C#のDataGridView 動的に生成する場合


(過去ログ 173 を表示中)

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

■99521 / inTopicNo.1)  C#のDataGridView 動的に生成する場合
  
□投稿者/ 星は昴 (38回)-(2022/04/21(Thu) 15:04:27)

分類:[C#] 

 DataGridView に乱数を表示させようとしているのですが、何回クリックしても最初画面表示されたままです。DataGridView をフォームデザイナーで貼り付けたときは正常に動きます。
 なぜ動的に生成した DataGridView ではまずいのでしょうか?

private void btnTable_Click(object sender, EventArgs e)
{
    const int N = 10000;
    const int M = 5;
    double[,] A = new double[N, M];
    var Rand = new Random();
    var DataGrid = new DataGridView();
    var table = new DataTable();
    DataGrid.Parent = splitContainer1.Panel2;
    DataGrid.Dock = DockStyle.Fill;

    for (int i = 0; i < N; i++)
        for (int j = 0; j < M; j++)
            A[i, j] = (double)Rand.Next(1, 20);

    // DataGridViewのデータをクリア
    DataGrid.DataSource = null;
    DataGrid.Rows.Clear();
    DataGrid.Columns.Clear();

    //コラムヘッダー
    for (int j = 0; j < M; j++)
        table.Columns.Add("num" + j.ToString());

    // 行データの追加
    DataGrid.SuspendLayout(); // Layoutの実行を保留する
    for (int i = 0; i < N; i++)
    {
        var dr = table.NewRow();
        for (int j = 0; j < M; j++)
            dr[j] = A[i, j];
        table.Rows.Add(dr);
    }

    DataGrid.DataSource = table; // DataTableをDataGridViewにバインド
    DataGrid.ResumeLayout();  // 保留中のLayoutを再開する
    
    //Refresh() してもダメ!
    DataGrid.Refresh(); 
}

引用返信 編集キー/
■99524 / inTopicNo.2)  Re[1]: C#のDataGridView 動的に生成する場合
□投稿者/ とっちゃん (760回)-(2022/04/21(Thu) 15:59:48)
No99521 (星は昴 さん) に返信
>  DataGridView に乱数を表示させようとしているのですが、何回クリックしても最初画面表示されたままです。DataGridView をフォームデザイナーで貼り付けたときは正常に動きます。
>  なぜ動的に生成した DataGridView ではまずいのでしょうか?

クリックする前に張り付いていたDataGridViewを表示したままにしているからではないでしょうか?(結果的に隠れた状態)
この場合、DataGridViewを新たに用意するのではなく、DataSourceに割り当てている
DataTable だけ変更すればいいように思います。

段取り的には、
var DataGrid = new DataGridView();
としている箇所を
var DataGrid = dataGridView1; // 実際にデザイナーで張り付けたコントロールを指定
とし、
DataGridViewと親の関係処理を行っている部分をカットしてやればいいように思いますが、それでは都合が悪い何かがあるのでしょうか?



引用返信 編集キー/
■99526 / inTopicNo.3)  Re[1]: C#のDataGridView 動的に生成する場合
□投稿者/ 魔界の仮面弁士 (3333回)-(2022/04/21(Thu) 17:29:43)
No99521 (星は昴 さん) に返信
> 何回クリックしても最初画面表示されたままです。
> DataGridView をフォームデザイナーで貼り付けたときは正常に動きます。

元々画面に貼ってある DataGridView コントロールがあるのですよね。
それを使いまわずに、新しいコントロールを生成(new)している意図が分からなかったです。
SuspendLayout/ResumeLayout している意図も不明瞭。


> なぜ動的に生成した DataGridView ではまずいのでしょうか?

もしも「ボタンを押すたびに DataGridView を動的に生成したい」のであれば、
その新しいグリッドを、どの座標にどのサイズで配置するのかというコードも必要です。
 DataGrid.Location = 〜;
 DataGrid.Size = = 〜;
 this.Controls.Add(DataGrid);

今は「作るだけ作って、どこにも表示させていない」状態ですね。
フォームに貼らずに、かといって Dispose での処分もしていない状況。


> var DataGrid = new DataGridView();
System.Windows.Forms.DataGrid という物はあるので、
System.Windows.Forms.DataGridView の変数名を
"DataGrid" にすることにちょっと違和感があります。

https://docs.microsoft.com/ja-jp/dotnet/desktop/winforms/controls/differences-between-the-windows-forms-datagridview-and-datagrid-controls?view=netframeworkdesktop-4.8

まぁ予約語というわけではないので、文法的な問題は無いのですけれどね。
引用返信 編集キー/
■99527 / inTopicNo.4)  Re[2]: C#のDataGridView 動的に生成する場合
□投稿者/ 星は昴 (39回)-(2022/04/21(Thu) 19:16:51)
> 元々画面に貼ってある DataGridView コントロールがあるのですよね。
 ありません。元々画面に貼ってある DataGridViewのときはうまくいくことはわかっていますので。動的に生成したときの動作を知りたかったのです。
 
> もしも「ボタンを押すたびに DataGridView を動的に生成したい」のであれば、
> その新しいグリッドを、どの座標にどのサイズで配置するのかというコードも必要です。
>  DataGrid.Location = 〜;
>  DataGrid.Size = = 〜;
>  this.Controls.Add(DataGrid);

> 今は「作るだけ作って、どこにも表示させていない」状態ですね。
> フォームに貼らずに、かといって Dispose での処分もしていない状況。
 なるほどなるほど。

> System.Windows.Forms.DataGrid という物はあるので、
> "DataGrid" にすることにちょっと違和感があります
 へー、これも知りませんでした。

 丁寧な回答まことにありがとうございました。
 とっちゃんさんにもお礼申し上げます。




解決済み
引用返信 編集キー/
■99528 / inTopicNo.5)  Re[3]: C#のDataGridView 動的に生成する場合
□投稿者/ 魔界の仮面弁士 (3334回)-(2022/04/21(Thu) 19:42:35)
2022/04/21(Thu) 19:43:59 編集(投稿者)

No99527 (星は昴 さん) に返信
>> this.Controls.Add(DataGrid);
>>今は「作るだけ作って、どこにも表示させていない」状態ですね。
>>フォームに貼らずに、かといって Dispose での処分もしていない状況。
>  なるほどなるほど。

以下蛇足:

フォームに直接貼る場合は this.Controls.Add ですが、
グループボックスやパネルなどのコンテナ上に配置する時は
groupBox1.Controls.Add や panel1.Controls.Add などとします。

コードから動的に配置する方法を使えば、
非コンテナ(たとえば Button や PictureBox 等)の配下に
配置することさえできます。(デザイナからだと貼れないですよね)
https://dobon.net/vb/dotnet/control/labelonpicturebox.html
https://dobon.net/vb/dotnet/form/formwithinform.html


逆に、配置したコントロールを動的に削除したい場合には
 Controls.Remove( DataGrid ); // または RemoveAt RemoveByKey
のようにします。ただし、意図的に取り除いたコントロールは、
DataGrid.Dispose(); を呼び出して「処分」する必要があることに注意してください。

画面上に貼ったままにしている場合は、上記の Dispose() は不要ですけれどね。
フォームが閉じられたときに、自動的に配下のコントロール群が処分される仕様なので。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -