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

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

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

ユーザーコントロール等の初回表示イベント

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

■96083 / inTopicNo.1)  ユーザーコントロール等の初回表示イベント
  
□投稿者/ freeway (1回)-(2020/10/20(Tue) 15:33:23)

分類:[VB.NET/VB2005 以降] 

VS2013使用
WinFormで使用しているDataGridViewで困ったことがあります。
UserControl上にDataGridViewを配置し、
上記UserControlをForm上で表示しています。
(UserControlを使用しているのは、グリッド等のコントロール群の差し替えを行うためです。)

UserControlのLoadイベントでDataGridViewにDataTableをバインドし、
グリッドのセルの設定(背景色等)の変更を行っているのですが、
これが反映されません。
色々と試してみると、どうやら完全にUserControl(DataGridView)が
完全に表示された状態でないとセルの色設定等が反映されないようで、
現在は仕方なくタイマーを使用して、少し待ってからセルの色設定等を行っています。

ただし、これは何だか気持ちの悪い方法なので、
せめて、UserControlやDataGridView等のコントロールの
初回表示イベントがないかを知りたく、質問させて頂きました。

ちなみに、UserControlの表示は親Formの初回表示と同じタイミングとは限らないため、
FormのShownは使用できません。

よろしくお願いします。
引用返信 編集キー/
■96086 / inTopicNo.2)  Re[1]: ユーザーコントロール等の初回表示イベント
□投稿者/ shu (1236回)-(2020/10/20(Tue) 15:51:39)
No96083 (freeway さん) に返信

こんな感じでどうでしょう?

Public Class UserControl1
    Public Sub New()
        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        AddHandler DataGridView1.Paint, AddressOf FirstPaint
    End Sub

    Private Sub FirstPaint(sender As Object, e As PaintEventArgs)
        RemoveHandler DataGridView1.Paint, AddressOf FirstPaint
        Dim tbl As New DataTable()
        With tbl.Columns
            .Add("column1")
            .Add("column2")
            .Add("column3")
        End With
        tbl.Rows.Add({"a1", "b1", "c1"})
        tbl.Rows.Add({"a2", "b2", "c2"})
        tbl.Rows.Add({"a3", "b3", "c3"})
        tbl.AcceptChanges()

        DataGridView1.DataSource = tbl
    End Sub

End Class

引用返信 編集キー/
■96094 / inTopicNo.3)  Re[2]: ユーザーコントロール等の初回表示イベント
□投稿者/ freeway (2回)-(2020/10/21(Wed) 12:09:59)
おお!!すごい!Paintイベントの初回を利用するという発想!
これには頭が下がる思いです。
早速試してみます!
手元に作業用PCがないので、後で結果を報告します。
引用返信 編集キー/
■96095 / inTopicNo.4)  Re[3]: ユーザーコントロール等の初回表示イベント
□投稿者/ Hongliang (1100回)-(2020/10/21(Wed) 12:30:14)
そもそもの話になりますが、DataGridViewの背景色等は、直接セルのプロパティを設定して回るのではなくて、CellFormattingイベントにてe.ColumnIndex/e.RowIndexに応じてe.CellStyleの各種プロパティに設定する形が基本になります。
引用返信 編集キー/
■96096 / inTopicNo.5)  Re[1]: ユーザーコントロール等の初回表示イベント
□投稿者/ 大谷刑部 (117回)-(2020/10/21(Wed) 13:24:39)
No96083 (freeway さん) に返信
> ちなみに、UserControlの表示は親Formの初回表示と同じタイミングとは限らないため、
> FormのShownは使用できません。
Activatedじゃためなの?
バインドするデータが大量でなければ、メモリリークとかの心配もさほどないと思うので、手っ取り早い方法ではある。

あと、後から設定する感の見た目があまり肉眼で気にならないレベルの環境なら、DataBindingCompleteでもいいような気はします。
値変えるとかソートを行うとかしなければ、何回も発動するとかしないので。
引用返信 編集キー/
■96098 / inTopicNo.6)  Re[4]: ユーザーコントロール等の初回表示イベント
□投稿者/ freeway (3回)-(2020/10/21(Wed) 15:47:37)
No96095 (Hongliang さん) に返信
> そもそもの話になりますが、DataGridViewの背景色等は、直接セルのプロパティを設定して回るのではなくて、CellFormattingイベントにてe.ColumnIndex/e.RowIndexに応じてe.CellStyleの各種プロパティに設定する形が基本になります。

コメントありがとうございます。
ちなみに、CellFormattingイベントは、どのようなタイミングで発生しますか?
実は、DataGridViewはただの縦×横のマスとして使っているので、
ユーザがボタンを押したタイミングで所定の計算を行い、その結果に応じて対応セルに色設定を行う
(ただし初期状態では決まった色パターンにしておく)というものですので、
ボタン押下後の計算結果が出てから、CellFormattingイベントを発生させるような命令を行うことになるでしょうか?
その場合、CellFormattingイベントで、先程の計算結果が参照できないとならないですよね...
逆に、不用意にCellFormattingイベントが発生しても困るのですが...
引用返信 編集キー/
■96099 / inTopicNo.7)  Re[2]: ユーザーコントロール等の初回表示イベント
□投稿者/ freeway (4回)-(2020/10/21(Wed) 15:52:14)
No96096 (大谷刑部 さん) に返信
> ■No96083 (freeway さん) に返信
>>ちなみに、UserControlの表示は親Formの初回表示と同じタイミングとは限らないため、
>>FormのShownは使用できません。
> Activatedじゃためなの?
> バインドするデータが大量でなければ、メモリリークとかの心配もさほどないと思うので、手っ取り早い方法ではある。
>
> あと、後から設定する感の見た目があまり肉眼で気にならないレベルの環境なら、DataBindingCompleteでもいいような気はします。
> 値変えるとかソートを行うとかしなければ、何回も発動するとかしないので。

コメントありがとうございます。
Activatedって、親Formのでしょうか?
元々FormがActivateであれば、このイベントは発生しないのではないでしょうか。

バインドをLoadイベントで行い、DataBindingCompleteで色設定を行ってもダメでした。
(タイマーで完全に表示しきってから色設定を行うとOK。)
引用返信 編集キー/
■96100 / inTopicNo.8)  Re[5]: ユーザーコントロール等の初回表示イベント
□投稿者/ 大谷刑部 (118回)-(2020/10/21(Wed) 16:07:11)
No96098 (freeway さん) に返信
> ■No96095 (Hongliang さん) に返信
>>そもそもの話になりますが、DataGridViewの背景色等は、直接セルのプロパティを設定して回るのではなくて、CellFormattingイベントにてe.ColumnIndex/e.RowIndexに応じてe.CellStyleの各種プロパティに設定する形が基本になります。
> コメントありがとうございます。
> ちなみに、CellFormattingイベントは、どのようなタイミングで発生しますか?
↓それくらいは自分で調べるなり、試してみればわかる話かと。
https://dobon.net/vb/dotnet/datagridview/cellformatting.html

> 実は、DataGridViewはただの縦×横のマスとして使っているので、
> ユーザがボタンを押したタイミングで所定の計算を行い、その結果に応じて対応セルに色設定を行う
そういう話で即時反映が必須ならCellFormattingが良さそうですが、
セルの値が変わるごとに発生するということでもあるので、無限ループ等が発生しないよう中のロジックには気を付けてください。

> 逆に、不用意にCellFormattingイベントが発生しても困るのですが...
VB6時代にchangeイベントが一文字ずつで発生するため無限ループの温床として嫌われたのと同種の懸念と思いますが、それも全部聞くんじゃなくて自分で試してみてはいかが?


引用返信 編集キー/
■96102 / inTopicNo.9)  Re[6]: ユーザーコントロール等の初回表示イベント
□投稿者/ freeway (5回)-(2020/10/21(Wed) 17:34:01)
2020/10/21(Wed) 17:36:44 編集(投稿者)

No96100 (大谷刑部 さん) に返信
> ■No96098 (freeway さん) に返信
>>ちなみに、CellFormattingイベントは、どのようなタイミングで発生しますか?
> ↓それくらいは自分で調べるなり、試してみればわかる話かと。
> https://dobon.net/vb/dotnet/datagridview/cellformatting.html

セル値が変わればCellFormattingイベントが発生するであろうことは分かっていたのですが、
そもそも今回のケースではデータバインド後のセルの値は変わらないので、どうやって使うのかな、と思っていたのです。
わざわざInvalidateみたいなことをするのであれば、このイベントを使う意味はないし。

>> 逆に、不用意にCellFormattingイベントが発生しても困るのですが...
> VB6時代にchangeイベントが一文字ずつで発生するため無限ループの温床として嫌われたのと同種の懸念と思いますが、それも全部聞くんじゃなくて自分で試してみてはいかが?

そもそも、なぜCellFormattingイベントを奨めたのか分かりませんので、聞いたっていいじゃないですか。
「これを使え。詳細は自分で調べろ」となって、自分で調べたら全然役に立たなかった、となっては気の毒に思いませんか?
少なくとも聞く権利はあります。もちろん答えてもらう義務はありません。
引用返信 編集キー/
■96103 / inTopicNo.10)  Re[7]: ユーザーコントロール等の初回表示イベント
□投稿者/ 大谷刑部 (119回)-(2020/10/21(Wed) 17:53:27)
No96102 (freeway さん) に返信
> 2020/10/21(Wed) 17:36:44 編集(投稿者)
>
> ■No96100 (大谷刑部 さん) に返信
>>■No96098 (freeway さん) に返信
> >>ちなみに、CellFormattingイベントは、どのようなタイミングで発生しますか?
>>↓それくらいは自分で調べるなり、試してみればわかる話かと。
>>https://dobon.net/vb/dotnet/datagridview/cellformatting.html
>
> セル値が変わればCellFormattingイベントが発生するであろうことは分かっていたのですが、
> そもそも今回のケースではデータバインド後のセルの値は変わらないので、どうやって使うのかな、と思っていたのです。
> わざわざInvalidateみたいなことをするのであれば、このイベントを使う意味はないし。
CellFormatting自体が不規則に発生するというよりは、データバインドするデータがDBのテーブルまたはデータテーブル等と連動している場合、
データエラー(例:Not null制約がかかっているデータが未入力)が発生する場合、アプリエラー発生したりするので、
DataErrorイベントとかで関連性チェック以外の最低限のチェックとデフォルト値の設定とかはしといた方がいいですね。
なのでイベントの併用は必要になると思います。


> >> 逆に、不用意にCellFormattingイベントが発生しても困るのですが...
>>VB6時代にchangeイベントが一文字ずつで発生するため無限ループの温床として嫌われたのと同種の懸念と思いますが、それも全部聞くんじゃなくて自分で試してみてはいかが?
>
> そもそも、なぜCellFormattingイベントを奨めたのか分かりませんので、聞いたっていいじゃないですか。
> 「これを使え。詳細は自分で調べろ」となって、自分で調べたら全然役に立たなかった、となっては気の毒に思いませんか?
> 少なくとも聞く権利はあります。もちろん答えてもらう義務はありません。
いや、権利とかの問題じゃなくて。
丸投げする前にデバッグぐらいして、使えそうかあたりをつけるのはプログラム作るなら当然すべきことですよ。
あなたの本業わかりませんが、プロならなおさら。
あなただけじゃなく、前提条件教えろとか情報小出しにするなと回答者に怒られてる質問者が多いのはそういうことと思いますけど。
忙しい職業プログラマーが善意で答えてくれてることが多いんですから。この手の掲示板。
本来、プロに聞いたらお金発生するのが普通ですよ。MSとかオラクルはそうでしょ?

引用返信 編集キー/
■96107 / inTopicNo.11)  Re[3]: ユーザーコントロール等の初回表示イベント
□投稿者/ Hongliang (1101回)-(2020/10/21(Wed) 19:01:32)
まず、私はCellFormattingを使うのが基本だといっただけで、それが唯一の解法だなどといったわけではないです。

https://docs.microsoft.com/en-us/dotnet/desktop/winforms/controls/best-practices-for-scaling-the-windows-forms-datagridview-control?view=netframeworkdesktop-4.8
ここにあるDataGridViewの実装のベストプラクティスの1つなのですが、各セルにStyleを設定するとパフォーマンスが悪化するというのが挙げられています。
セル単位でStyleを設定するのにはCellFormattingの使用が勧められています。

また、今回のようなバインディングなどのタイミングによる影響がない点も利点の一つでしょう。

> ちなみに、CellFormattingイベントは、どのようなタイミングで発生しますか?
> 実は、DataGridViewはただの縦×横のマスとして使っているので、
> ユーザがボタンを押したタイミングで所定の計算を行い、その結果に応じて対応セルに色設定を行う
> (ただし初期状態では決まった色パターンにしておく)というものですので、
> ボタン押下後の計算結果が出てから、CellFormattingイベントを発生させるような命令を行うことになるでしょうか?
> その場合、CellFormattingイベントで、先程の計算結果が参照できないとならないですよね...
CellFomattingは想像以上に頻繁に呼び出されます(それこそスクロールしただけで発生します)が、それは特に気にする必要はありません。
基本的には、
1. 二次元配列等に計算結果を格納しておく
2. 計算が発生したら、完了後に1に格納してから影響のあるセルを指定してDataGridView::InvalidateCellメソッドを呼び出す
3. CellFormattingイベントで、1を参照してe.Styleに各種値を設定する
という手順を取ります。
(通常は、1はDataGridViewにバインドするデータそのものなので手間が省けるのですが)

> 逆に、不用意にCellFormattingイベントが発生しても困るのですが...
普通に設計すれば困ることはないように思いますが、どんな懸念があるのでしょうか?


もちろん、各セルにDataGridViewCell::Styleを設定していく方法でパフォーマンスへの影響が問題にならないのであれば、そうしても構いません。
私の先の投稿は、そういう方法もあるよというのを提示しただけですので。
引用返信 編集キー/
■96118 / inTopicNo.12)  Re[8]: ユーザーコントロール等の初回表示イベント
□投稿者/ freeway (6回)-(2020/10/22(Thu) 10:19:00)
shuさんの方法で問題を解決できました!
ありがとうございました!

No96103 (大谷刑部 さん) に返信

> 忙しい職業プログラマーが善意で答えてくれてることが多いんですから。この手の掲示板。
> 本来、プロに聞いたらお金発生するのが普通ですよ。MSとかオラクルはそうでしょ?

これは十分理解しています。

>>少なくとも聞く権利はあります。もちろん答えてもらう義務はありません。
> いや、権利とかの問題じゃなくて。
> 丸投げする前にデバッグぐらいして、使えそうかあたりをつけるのはプログラム作るなら当然すべきことですよ。

普通、丸投げというのは、「こういうものを作りたいからコードを教えてくれ」というものです。
CellFormattingイベントがどういうときに発生するか、なんていうのは知識を得るための質問であり、丸投げのうちに入りません。
答えたくなければ答えなければいいのです。
横から「それくらいは自分で調べろ」と言いながら無用な情報を並べ立てる方が、こちらとしては迷惑な話です。
こういう人は本当はヒマなんじゃないかとも思ってしまいます。
「デバッグ」?何を言っているんでしょう?

そもそも、こちらの質問は、UserControlや他のコントロールの初回表示イベントの検知方法なので、
CellFormattingに関することは、一種の脱線だと思っています。
#Hongliangさんも「そもそもの話」としているので、本題ではないと理解しています。
 前提として、こちらが懸念しているのはセル色の話だけではないので。

本題に対してまともな回答も頂けずに、脱線話の挙げ足を取られても困ります。
あなたは本当にこちらの質問の意図を理解していますか?
それを理解していなければ回答してはいけないと思っています。
(情報提供や情報不足の指摘は別で、これは有難く頂戴します。)

質問者の心得的なことを書かれていましたが、回答者の心得も無視できないと思います。
このサイトの今までの質問スレッドを拝見しましたが、
「この人に回答してもらいたくない」と思った人が2名いました。
一人は、色々と調べた所、「波乗」と呼ばれる人。
さて、もう一人は。

解決済み
引用返信 編集キー/
■96120 / inTopicNo.13)  Re[9]: ユーザーコントロール等の初回表示イベント
□投稿者/ 大谷刑部 (121回)-(2020/10/22(Thu) 11:35:36)
No96118 (freeway さん) に返信
> shuさんの方法で問題を解決できました!
> ありがとうございました!

最初の回答を採用したなら、後の質問無駄だよね。
じゃあなんでわざわざ、イベントとの内容をふかぼりしたのって話になる。

> CellFormattingに関することは、一種の脱線だと思っています。
それで質問した意味が分からん。
今回はこれこれで最初の回答を採用しましたって書けば終わりの話。

> 質問者の心得的なことを書かれていましたが、回答者の心得も無視できないと思います。
これは言わなくていい話。
不快に思ったのなら無視すればいい話で、それならばこちらもそういう対応をする。
いちいち毒づく意味が分からん。
無駄な嫌味。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


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

このトピックに書きこむ