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

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

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

Re[4]: DataGridViewの内容DataGridViewに表示


(過去ログ 122 を表示中)

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

■73006 / inTopicNo.1)  DataGridViewの内容DataGridViewに表示
  
□投稿者/ 巻 (1回)-(2014/08/10(Sun) 19:15:48)

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

2014/08/10(Sun) 19:17:32 編集(投稿者)

使用ソフト
Microsoft Visual Studio 2010
.net framework 4


DataGridViewをフォーム上に2つ設置し、DataGridView1の行をクリックするとその内容がDataGridView2に表示されるアプリケーションを開発しています。

DataGridView1(以下dgv1)にはSQL文で呼び出したテーブルの内容を表示させており、DataGridView2(以下dgv2)には何も表示させていません。

質問内容についてですが、dgv2だけは直接セルに書き込む事が出来るようになっています。
ですが、dgv1の行をクリックすると、dgv2に直接書き込んだ内容が上書きされてしまいます。

dgv1の行をクリックした内容を優先しdgv2に直接書き込んだ内容は
変数に入れておきあとからdgv2に再度書き込むという形を取りたいのですが、どうしたら良いでしょうか?

よろしくお願い致します。
引用返信 編集キー/
■73011 / inTopicNo.2)  Re[1]: DataGridViewの内容DataGridViewに表示
□投稿者/ WebSurfer (317回)-(2014/08/11(Mon) 12:29:43)
No73006 (巻 さん) に返信
> dgv1の行をクリックした内容を優先しdgv2に直接書き込んだ内容は
> 変数に入れておきあとからdgv2に再度書き込むという形を取りたいのですが、どうしたら良いでしょうか?

ここのところの意味が分かりません。

dgv1 の行をクリックした時、クリックした dgv1 の行データを dgv2 の 1 行目に
表示して、もともと dgv2 に表示されていたデータを 2 行目以降にずらして表示し
たいということですか?

であれば、DataGridViewRowCollection.Insert メソッドを使ってできませんか?
引用返信 編集キー/
■73012 / inTopicNo.3)  Re[1]: DataGridViewの内容DataGridViewに表示
□投稿者/ 魔界の仮面弁士 (73回)-(2014/08/11(Mon) 13:24:49)
No73006 (巻 さん) に返信
> DataGridViewをフォーム上に2つ設置し、DataGridView1の行をクリックすると
> その内容がDataGridView2に表示されるアプリケーションを開発しています。

DataGrid1 の選択行に対する明細データを、DataGridView2 に表示させるということでしょうか?

(例)
DataGridView1 が注文書の宛名情報、DataGridView2 がその注文に含まれる商品の一覧。
DataGridView1 が日ごとの来場者数、DataGridView2 がその日の1時間ごとの来場者数。
DataGridView1 が受信メールの一覧、DataGridView2 がそのメールの内容。

もしそうであれば、DataSet 内でリレーションを貼っておき、その親子情報を
BindingSource を通じて DataGridView にセットすれば、DataGridView1 に連動して
DataGridView2 の内容が切り替わるようになります。
http://msdn.microsoft.com/ja-jp/library/y8c0cxey.aspx?cs-lang=vb


もしも 2 つの DataGridView を自動的に連動させたくない場合は、リレーションを経由せずに
DataTable/DataView を直接バインドすれば OK です。


もしくは、データバインドさせるのは DataGridView1 だけにしておき、
DataGridView2 は、DataSource を未設定のまま、非バインド状態で管理するという選択肢もあります。


> 質問内容についてですが、dgv2だけは直接セルに書き込む事が出来るようになっています。
> ですが、dgv1の行をクリックすると、dgv2に直接書き込んだ内容が上書きされてしまいます。
dgv1 / dgv2 とは、DataGridView1 / DataGridView2 のことですね。
dgv1 と dgv2 とに対して、DataSource やイベント等、どのようにセットしているのでしょうか?


> dgv1の行をクリックした内容を優先しdgv2に直接書き込んだ内容は
> 変数に入れておきあとからdgv2に再度書き込むという形を取りたいのですが、どうしたら良いでしょうか?
「どのようなコードを書いているのか」が提示されていないため、
具体的な修正コードを提案することは出来ませんが、現在提示されている内容から
考え方を整理してみると、下記の「案3」を実施したいということなのでしょうか。

前提条件1:DataGridView1は ReadOnly、DataGridView2は直接編集可能
前提条件2:DataGridView1の行をクリックするとその内容がDataGridView2に表示される

現在の問題点:DataGridView2が編集中の場合、DataGridView1 を選択すると DataGrid2 の情報が上書きされてしまう。

実際に望む動作:

→案1:DataGridView2 の編集が完了するまでは、その内容が上書きされないよう、DataGridView1 を使用不可にしておきたい。
→案2:DataGridView2 の編集中に DataGridView1 を選択した場合、DataGridView2 の内容を上書きするかどうかを問い合わせるようにしたい。
→案3:DataGridView1 で別の行を選択すると、編集中の DataGridView2 の内容が上書きされるが、再度、DataGridView1 で元の行を再選択すると、DataGridView2 には先ほど編集していた内容が復元されるようにしたい。
引用返信 編集キー/
■73015 / inTopicNo.4)  Re[2]: DataGridViewの内容DataGridViewに表示
□投稿者/ 巻 (2回)-(2014/08/11(Mon) 20:13:11)
No73011 (WebSurfer さん) に返信

お返事を頂いたにも関わらず返答が遅くなってしまい申し訳ありません。

> ■No73006 (巻 さん) に返信
>>dgv1の行をクリックした内容を優先しdgv2に直接書き込んだ内容は
>>変数に入れておきあとからdgv2に再度書き込むという形を取りたいのですが、どうしたら良いでしょうか?
>
> ここのところの意味が分かりません。

拙い文章で申し訳ないです。

> dgv1 の行をクリックした時、クリックした dgv1 の行データを dgv2 の 1 行目に
> 表示して、もともと dgv2 に表示されていたデータを 2 行目以降にずらして表示し
> たいということですか?

はい、まさにその通りです。


> であれば、DataGridViewRowCollection.Insert メソッドを使ってできませんか?

お教えいただいた通りDataGridViewRowCollection.Insertメソッドを使ってみたところ
[データバインドされている行に新しく追加することはできません]
といったエラーが出てしまい、追加する事は出来ませんでした。
引用返信 編集キー/
■73016 / inTopicNo.5)  Re[2]: DataGridViewの内容DataGridViewに表示
□投稿者/ 巻 (3回)-(2014/08/11(Mon) 20:41:50)
No73012 (魔界の仮面弁士 さん) に返信

返答が遅くなってしまい申し訳ありません。
返信ありがとうございます。

> ■No73006 (巻 さん) に返信
>>DataGridViewをフォーム上に2つ設置し、DataGridView1の行をクリックすると
>>その内容がDataGridView2に表示されるアプリケーションを開発しています。
>
> DataGrid1 の選択行に対する明細データを、DataGridView2 に表示させるということでしょうか?

いえ、そうではなくWebSurferさんがおっしゃられていたように
[dgv1 の行データを dgv2 の 1 行目に表示して、もともと dgv2 に表示されていたデータを 2 行目以降にずらして表示したい]
という事をしたいと考えております。
詳しい例、URLありがとうございます。勉強させて頂きます。


>>質問内容についてですが、dgv2だけは直接セルに書き込む事が出来るようになっています。
>>ですが、dgv1の行をクリックすると、dgv2に直接書き込んだ内容が上書きされてしまいます。
> dgv1 / dgv2 とは、DataGridView1 / DataGridView2 のことですね。
> dgv1 と dgv2 とに対して、DataSource やイベント等、どのようにセットしているのでしょうか?

dgv1にはSQL文を使いテーブルを呼び出し表示させるのみです。ただ、セル選択ではなく行選択になるようにしています。
dgv2にもSQL文を使いdgv1と同じテーブルを呼び出していますが、新規行のみ表示させたかったので

WHERE [テーブル名] LIKE [テーブルに存在しない値]

として呼び出し、dgv2には新規行しか表示させないという形を取っています。

そして、dgv1の行をクリックすると、dgv1のクリックされた行の値を変数Testに入れ、
それをdgv2でも呼び出しているテーブルから探し出し、表示されるという事をやっています。



>>dgv1の行をクリックした内容を優先しdgv2に直接書き込んだ内容は
>>変数に入れておきあとからdgv2に再度書き込むという形を取りたいのですが、どうしたら良いでしょうか?
> 「どのようなコードを書いているのか」が提示されていないため、
> 具体的な修正コードを提案することは出来ませんが、現在提示されている内容から
> 考え方を整理してみると、下記の「案3」を実施したいということなのでしょうか。
>
> 前提条件1:DataGridView1は ReadOnly、DataGridView2は直接編集可能
> 前提条件2:DataGridView1の行をクリックするとその内容がDataGridView2に表示される
>
> 現在の問題点:DataGridView2が編集中の場合、DataGridView1 を選択すると DataGrid2 の情報が上書きされてしまう。
>
> 実際に望む動作:
>
> →案1:DataGridView2 の編集が完了するまでは、その内容が上書きされないよう、DataGridView1 を使用不可にしておきたい。
> →案2:DataGridView2 の編集中に DataGridView1 を選択した場合、DataGridView2 の内容を上書きするかどうかを問い合わせるようにしたい。
> →案3:DataGridView1 で別の行を選択すると、編集中の DataGridView2 の内容が上書きされるが、再度、DataGridView1 で元の行を再選択すると、DataGridView2 には先ほど編集していた内容が復元されるようにしたい。

そうです、錯乱した考えを纏めて下さりありがとうございます…。
まさに案3の[内容が復元される]がやりたい事です。
引用返信 編集キー/
■73017 / inTopicNo.6)  Re[3]: DataGridViewの内容DataGridViewに表示
□投稿者/ 魔界の仮面弁士 (75回)-(2014/08/11(Mon) 20:42:34)
No73015 (巻 さん) に返信
>>であれば、DataGridViewRowCollection.Insert メソッドを使ってできませんか?
> お教えいただいた通りDataGridViewRowCollection.Insertメソッドを使ってみたところ
> [データバインドされている行に新しく追加することはできません]
> といったエラーが出てしまい、追加する事は出来ませんでした。

DataGridView2.Rows.Insert を使う場合は、DataGrid2には「DataSource を使わずに表示」してください。
すなわち、.DataSource を Nothing にしたまま、.Rows.Add と .Rows.Insert を使って行登録していくか、
もしくは .RowCount で全体行数を事前に定めた後で、DataGridView2(x, y).Value を読み書きします。


一方、「DataGridView2.DataSource を使って表示」する場合は、データソースの並び順を調整することで
対応してみて下さい。たとえば DataTable に、非表示の「並び替え用の列」を別途用意しておき、
その列を DataView や BindingSource の Sort プロパティに渡すようにするなど。
引用返信 編集キー/
■73022 / inTopicNo.7)  Re[3]: DataGridViewの内容DataGridViewに表示
□投稿者/ WebSurfer (318回)-(2014/08/11(Mon) 23:40:29)
No73015 (巻 さん) に返信
> お教えいただいた通りDataGridViewRowCollection.Insertメソッドを使ってみたところ
> [データバインドされている行に新しく追加することはできません]
> といったエラーが出てしまい、追加する事は出来ませんでした。

何をバインドしているのですか。例えば DataTable をバインドしているなら、DataGridView を
直接操作するのではなく、DataTable に行を追加しないとダメなのでは?
引用返信 編集キー/
■73024 / inTopicNo.8)  Re[3]: DataGridViewの内容DataGridViewに表示
□投稿者/ 魔界の仮面弁士 (78回)-(2014/08/12(Tue) 03:27:23)
No73016 (巻 さん) に返信
> [dgv1 の行データを dgv2 の 1 行目に表示して、もともと dgv2 に表示されていたデータを 2 行目以降にずらして表示したい]
> という事をしたいと考えております。

dgv1 をクリックすると、dgv2 の先頭にそれが表示されるということのようですが、
再度 dgv1 で同じ行をクリックした場合、dgv2 側に重複行が挿入されれば良いのでしょうか。


DataSet や DataTable をバインドしている場合、dataTable.Rows.InsertAt にて、特定位置への「行の挿入」ができます。
BindingSource をバインドしている場合、bindingSource.Insert にて挿入できます。

ただし、元データ側に行を挿入したとしても、DataGridView の 列ヘッダをクリックしていた場合や、
DataTable.Sort や BindingSource.Sort などで、ソート指定がされている場合、
DataGridView への並び順はそちらが優先されます。


DataGridView 側のソート機能をカスタマイズしたい場合には、下記が参考になるかも知れません。
http://msdn.microsoft.com/ja-jp/library/ms171608.aspx?cs-lang=vb


とりあえず、dataTable.Rows.InsertAt を使った例:

Public Class Form1
    Private tbl1 As DataTable
    Private tbl2 As DataTable

#Region "画面構成"
    Private WithEvents dgv1 As New DataGridView()
    Private WithEvents dgv2 As New DataGridView()
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'デザイン時に設定しておいてもOK
        Dim panel As New SplitContainer()
        panel.Orientation = Orientation.Horizontal
        panel.Panel1.Controls.Add(dgv1)
        panel.Panel2.Controls.Add(dgv2)
        dgv1.Dock = DockStyle.Fill
        dgv2.Dock = DockStyle.Fill
        panel.Dock = DockStyle.Fill
        Controls.Add(panel)
        dgv1.MultiSelect = False
        dgv1.ReadOnly = True
        dgv1.AllowUserToAddRows = False
        dgv1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        dgv2.SelectionMode = DataGridViewSelectionMode.CellSelect
        dgv2.EditMode = DataGridViewEditMode.EditOnEnter
        dgv2.AllowUserToAddRows = False

        'データの表示
        tbl1 = CreateSampleData()
        tbl2 = tbl1.Clone()
        tbl2.PrimaryKey = Nothing   '重複登録を許可
        dgv2.DataSource = tbl2
        dgv1.DataSource = tbl1
        dgv1.ClearSelection()

        'dgv2 側がソート可能だと話がややこしくなるので、NotSortable にしておく
        For Each c As DataGridViewColumn In dgv2.Columns
            c.SortMode = DataGridViewColumnSortMode.NotSortable
        Next
    End Sub
#End Region


#Region "テスト用データ"
    ''' <summary>テスト用データ</summary>
    Private Function CreateSampleData() As DataTable
        Dim dsSample As New DataSet("Sample")
        Dim tbl1 = dsSample.Tables.Add("Table1")
        tbl1.PrimaryKey = New DataColumn() {tbl1.Columns.Add("ID", GetType(Integer))}
        tbl1.Columns.Add("User", GetType(String))
        tbl1.Rows.Add(100, "山田")
        tbl1.Rows.Add(200, "田中")
        tbl1.Rows.Add(300, "山中")
        tbl1.Rows.Add(400, "中田")
        Return tbl1
    End Function
#End Region

    ''' <summary>dgv1 でクリックした行を、dgv2 の先頭に複写</summary>
    Private Sub dgv1_MouseClick(sender As Object, e As MouseEventArgs) Handles dgv1.MouseClick
        Dim ht = dgv1.HitTest(e.X, e.Y)
        If ht.RowIndex >= 0 Then
            '選択した行の取得
            Dim newRow = tbl2.NewRow()
            newRow.ItemArray = DirectCast(dgv1.Rows(ht.RowIndex).DataBoundItem, DataRowView).Row.ItemArray

            '★先頭行に挿入★
            tbl2.Rows.InsertAt(newRow, 0)
            newRow.AcceptChanges()

            '追加した行をカレント行にしておく
            dgv1.ClearSelection()
            dgv2.CurrentCell = dgv2(0, 0)
            dgv2.BeginEdit(True)
        End If
    End Sub
End Class

引用返信 編集キー/
■73037 / inTopicNo.9)  Re[4]: DataGridViewの内容DataGridViewに表示
□投稿者/ 巻 (4回)-(2014/08/12(Tue) 20:05:48)
2014/08/12(Tue) 22:15:04 編集(投稿者)

No73024 (魔界の仮面弁士 さん) に返信

回答ありがとうございます。

> とりあえず、dataTable.Rows.InsertAt を使った例

教えて頂いた例を試してみたところ、希望通り動くようになりました。

同時で申し訳ありませんが、WebSurferさん、魔界の仮面弁士さん、本当にありがとうございました。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -