DataGridViewについて への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 凡人  (高校生) 投稿日時 2012/2/29 01:36:36
返信おそくなり、大変申し訳ありません...

>魔界の仮面弁士さま

>セルが着色されているの DataGridView のことでしょうか?
>FrameManager という用語や製品は聞いたことがありませんが、先の dosStudio の用語でしょうか?
説明不足ですみません...
そのとおりです。

>たとえばこんな感じ。ここでは、ボタンを押すごとに色付きのセルを追加しています。
実践的なソースコードありがとうございます!
なるほど!
CellFormattingという方法もあるのですね!

やっとDataGriViewのバインドの使用方法が理解できたと思います...
これを参考にして、実装してみたいと思います!

ありがとうございました!
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/2/25 01:21:57
> 具体的にどのようにDataSetと連携すればよいのでしょうか...?

DataSet(DataTable) を、DataGridView の DataSource にセットすれば OK です。
データの読み書きは、DataGridView ではなく、DataTable に対して行うようにします。


たとえばこんな感じ。ここでは、ボタンを押すごとに色付きのセルを追加しています。

各セルには、ボタンを押した時刻も表示させています。
列ヘッダーをクリックすれば、ソートも行われます。

Partial Public Class Form1

    Private tbl As DataTable

    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
        '今回はコードで DataTable の定義を記述していますが、型付きDataSet を使うのもお奨めです。 
        tbl = New DataTable()
        tbl.Columns.Add("時刻"GetType(Date))
        tbl.Columns.Add("背景色"GetType(Color))

        'データバインド関連の情報。コードではなく、デザイン時に指定しておいても OK。 
        Dim col As New DataGridViewTextBoxColumn()
        col.HeaderText = "Time"
        col.DataPropertyName = "時刻"
        col.DefaultCellStyle.Format = "HH:mm:ss.ffff"
        col.ReadOnly = True
        DataGridView1.Columns.Add(col)

        DataGridView1.AutoGenerateColumns = False  'True の場合は、背景色の列も追加される 
        DataGridView1.AllowUserToAddRows = False
        DataGridView1.DataSource = tbl    '★DataTable をセット 
        DataGridView1.DefaultCellStyle.SelectionBackColor = SystemColors.Window
        DataGridView1.DefaultCellStyle.SelectionForeColor = SystemColors.WindowText
    End Sub

    Private Sub DataGridView1_CellFormatting(ByVal sender As Object, _
        ByVal e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting

        If e.RowIndex >= 0 Then   'RowIndex = -1 は列ヘッダーの行を指す 

            'DataGridView1.InvalidateRow(e.RowIndex)   'これは、行全体を再描画する場合に利用 

            'バインド元の行を取り出す場合は、DataBoundItem プロパティを利用する 
            Dim rowView As DataRowView = TryCast(DataGridView1.Rows(e.RowIndex).DataBoundItem, DataRowView)
            If rowView IsNot Nothing Then
                Dim row As DataRow = rowView.Row

                e.CellStyle.BackColor = DirectCast(row("背景色"), Color)
            End If
        End If
    End Sub

    '先頭にピンクの行を追加 
    Private Sub Button1_Click(ByVal sender As ObjectByVal e As EventArgs) Handles Button1.Click
        Dim newRow As DataRow = tbl.NewRow()
        newRow("時刻") = Now
        newRow("背景色") = Color.Pink
        tbl.Rows.InsertAt(newRow, 0)
    End Sub

    '末尾に水色の行を追加 
    Private Sub Button2_Click(ByVal sender As ObjectByVal e As EventArgs) Handles Button2.Click
        Dim newRow As DataRow = tbl.NewRow()
        newRow("時刻") = Now
        newRow("背景色") = Color.LightCyan
        tbl.Rows.Add(newRow)
    End Sub

    '先頭にランダムな色を追加 
    Private Sub Button3_Click(ByVal sender As ObjectByVal e As EventArgs) Handles Button3.Click
        Dim r As New Random()
        Dim newRow As DataRow = tbl.NewRow()
        newRow("時刻") = Now
        newRow("背景色") = Color.FromArgb(255, r.Next(256), r.Next(256), r.Next(256))
        tbl.Rows.InsertAt(newRow, 0)
    End Sub
End Class
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/2/25 01:12:03
> (このサイトにあるScoreViewFormがDataGridViewの使用箇所です。)
どれが ScoreViewForm か分かりませんでしたが、
セルが着色されているの DataGridView のことでしょうか?

> このRowHeaderの値はFrameManagerに値によって逐次変更されていき、
FrameManager という用語や製品は聞いたことがありませんが、先の dosStudio の用語でしょうか?
名前だけで検索したら、このようなものが ヒットしましたが…。
http://www.mcframe.com/product/develop/frameManager.html


> また色を使って表現するため、DataGridViewとの連携はむずかしいかなと思ったのですが...
着色する場所や色は、データの内容またはセル位置によって決まるはずですよね。

データ数が多い場合は、色設定は各セルに対して直接指定するのではなく、
イベント処理を用いて指定した方が、都合が良いかと思います。
http://dobon.net/vb/dotnet/datagridview/index.html

たとえば下記では、5行ごとに背景色を黄色にしています。
また、セルに 1~3 のいずれかを入力すると、赤・緑・青になります。

Partial Public Class Form1
    Public Sub New()
        InitializeComponent()
        DataGridView1.AllowUserToAddRows = False
        DataGridView1.RowCount = 30
        DataGridView1.ColumnCount = 3
        DataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
    End Sub

    Private Sub DataGridView1_CellFormatting(ByVal sender As Object, _
        ByVal e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting

        If (e.RowIndex + 1) Mod 5 = 0 Then
            e.CellStyle.BackColor = Color.Yellow
        End If

        If e.Value = "1" Then
            e.CellStyle.BackColor = Color.Red
        ElseIf e.Value = "2" Then
            e.CellStyle.BackColor = Color.Green
        ElseIf e.Value = "3" Then
            e.CellStyle.BackColor = Color.Blue
        End If
    End Sub
End Class
投稿者 凡人  (高校生) 投稿日時 2012/2/24 03:40:59
>魔界の仮面弁士さま

http://www.bonprosoft.com/modules/blog/?page_id=202
このようにDataGridViewを使用してます。
(このサイトにあるScoreViewFormがDataGridViewの使用箇所です。)

このRowHeaderの値はFrameManagerに値によって逐次変更されていき、また色を使って表現するため、DataGridViewとの連携はむずかしいかなと思ったのですが...

このような場合、具体的にどのようにDataSetと連携すればよいのでしょうか...?
よろしくお願いします。

(ちなみに、このソフトではセーブデータはFrameManagerのアイテムとフレーム数とColumnIndexを記録し、読み込み時に再評価&描写しています)
投稿者 (削除されました)  () 投稿日時 2012/2/24 03:19:49
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/2/24 02:57:56
> リソース(確保分)の消費量が増える(と思うのですが...
そもそも、大量のデータを DataGridView 自身に管理させない方が良いでしょう。

データソースは別管理にするのが一般的な手法です。たとえばDataSet 等でデータを保持し、
それを DataGridView.DataSource にバインドすることを検討してみてください。
そうすれば、消費するリソースは見えている範囲+α程度で済みますし、
データを RowIndex に頼って管理する必要もなくなるはずです。


なお、データバインドですらリソース消費が問題なるようなケースでは、
DataGridView の仮想モードを利用することができます。難易度は上がりますが。
投稿者 凡人  (高校生) 投稿日時 2012/2/24 02:40:32
>魔界の仮面弁士さま

それも考えたのですが、その方法だと...
1.)DataGridViewには大量のデータを入力していく可能性があるため、下から入力するとなると、そこまでのセルを初期化することになってしまい、リソース(確保分)の消費量が増える(と思うのですが...)
2.)プログラムの流れが相当複雑になる。

2.)は頑張ればできるのですが、1.)の問題があるかな...と考えました。

もちろん魔界の仮面弁士さまが仰ったような方法しかないのであれば、その方法で進めるしかないのですが...
この方法以外に実現する方法はありますか?
よろしくお願いします...!
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/2/23 03:28:36
> これを下から順に0,1,2,3,...のように、流れを下から上にすることはできますか...?
「(行数 - 1) - RowIndex」で算出するだけでは駄目なのでしょうか。

たとえば総行数が4 なら、「0,1,2,3」は (3-0),(3-1),(3-2),(3-3) として
3,2,1,0 と求まりますよね。


ただし、DataGridView 上でデータをソートした場合、DataGridView 上の
RowIndex も入れ替わりますので、その点はご注意を。
投稿者 凡人  (高校生) 投稿日時 2012/2/23 01:01:55
こんばんは。

DataGridViewは通常上から順に入力していき、RowIndexも上から順番に0,1,2,3,...のように、流れとして「上から下へ」というようになっていますが...
これを下から順に0,1,2,3,...のように、流れを下から上にすることはできますか...?


コントロールの角度を指定できるコンテナやパネルがあればいいのですが...

環境はVB2010、WPFは訳があって使えません。

よろしくおねがいします!