none
DataGridViewの新規行追加数について、お尋ねします。 RRS feed

  • 質問

  • DataGridViewでの追加行を一行にとどめたいのです。

    サーバーからデータを引き出し、datatableを作成しそれをDataGridViewのデータソースとしています。
    読み取り専用時(ReadOnly=True)は、新規行なし(Me.DataGridView1.AllowUserToAddRows = False)。
    修正・削除・新規登録時(ReadOnly=False)は、新規行あり( Me.DataGridView1.AllowUserToAddRows =True)、としています。


    <症状>
    DtaGridViewでのデータ修正時に、新規行(*表示あり)をクリックしデータ入力するとその行は通常行となり、新たに新規行(New Row)が一行追加されます。
    これは、通常の正常動作です。

    しかし、新規行(New Row)をクリックし(何も入力しないで)、上の行(通常のデータ行)に戻りそこをクリックしてから、
    再度新規行にデータ入力します。

    すると、追加行が一行でなく、複数行追加となります。

    ” この追加数を、一行にしたいのです。”

    毎回、追加行は一行毎にして、複数行の追加を防止したいのです。

    コマンドボタン(行追加・行削除)を設けてのコードは作成しています、これはうまく動作しています。
    しかし、コマンドボタンを使用せずに上記の目的を果たしたいのです。

    YKsaila




    • 編集済み yksaila 2013年11月5日 5:37
    2013年11月5日 5:32

回答

  • 状況が今一歩わかりません。新規に追加する行が同時に2行現れるということでしょうか?しかし、それを実現させることは不可能、もしくは簡単ではないと思います。
    想像ですが、1行しか追加させないために何かロジックを組まれていないでしょうか? それが特定の条件下ではうまく動作していないということではないでしょうか?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    >新規に追加する行が同時に2行現れるということでしょうか?

    >何かロジックを組まれていないでしょうか? それが特定の条件下ではうまく動作していないということではないでしょうか?

    そうなのです。 ShiroYuki_Motoさんの書き込みからも、よくそれが分かりました。

    それで、いろいろやってみて、うまくいきました! 

    有難うございます、もっと早く相談すれば良かったかもしれないですね。

    以下、解決策です:

    行番号(LineNo)というものを設けています。この番号は、通し番号とは限りません(削除がありますので)。
    この行番号は、プログラム上必須で欠かせません。

    Private Sub DataGridView1_CellClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
    '-----略
    '二行目以降のLineNoに連番を振る(LineNo空白時)。'第一行(e.RowIndex= 0)は入力あるので除外。
    If Me.DataGridView1.CurrentRow.IsNewRow AndAlso e.RowIndex > 0 AndAlso IsDBNull(Me.DataGridView1.CurrentRow.Cells("LineNo").Value) Then  
        'e.RowIndex > 0 → 下記の(e.RowIndex - 1)を負にしないため。
       If Not IsDBNull(Me.DataGridView1.Rows(e.RowIndex - 1).Cells("ItemNo").Value) Then     '前の行のItemNoが空白でないとき
          Me.DataGridView1.CurrentRow.Cells("LineNo").Value = CInt(Me.DataGridView1.Rows(e.RowIndex - 1).Cells("LineNo").Value) + 1  '行番号加算:前行番号 + 1
           Me.DataGridView1.CurrentCell = Me.DataGridView1.Rows(e.RowIndex).Cells("A")
       End If
    End If
    '-----略
    End Sub

    上記のコードが原因でした!
    これを、CellValidated,CellValidatingにもっていっても、同じ現象でした。
    種々の多くの実験を試みましたが、不成功。 この10日間ほど、これに悩まされていました!
    RowValidatingでも、ダメでした。

    コードに問題があるのかもという疑念はあったのですが、確信が持てず、実は他の方法が有るのではと思って投稿しました。

    でも、お二人のご教示により、いろんな部分を削除していき原因探求することにしました。
    ここのFormだけで約4,000行ほどあるのですが、いろんな部分を削除していって、やはり上記のコードに問題があることを突き止めました。
    コード自体に誤りは無いのです。

    要するに:

    新規行をクリックしたときに、ある条件下では、この新規行(New Row)から抜け出せないようにすればよいのですが、これがうまくいっていませんでした。 (以前にも試みましたが、不成功でした。)


    下記のコードを加えました。成功しました!!
    '行への連番付与
     Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
      If Me.DataGridView1.CurrentRow.IsNewRow Then
        If Not IsDBNull(Me.DataGridView1.Rows(e.RowIndex).Cells("LineNo").Value) AndAlso IsDBNull(Me.DataGridView1.Rows(e.RowIndex).Cells("A").Value) Then
           Me.DataGridView1.CurrentCell = Me.DataGridView1.Rows(e.RowIndex).Cells("A")
            e.Cancel = True
        End If
      End If

     End Sub

    これで、成功です!

    新規行Click時に、LineNoをコードで表示します(手入力ではありません)が、その段階で何もせず上の通常行に移行すると新規行のLineNoは消えます(多分、手入力でないから)。 しかし、何かの信号は残っているみたいで、その後に新規行に入力すると複数行の追加に成ります。 これを防ぎたかったのですが、この時、新規行から抜けだせなくするコードがうまく書けていなかったのが原因でした。

    出来てみると何でも簡単に見えます

    10日間も悩み続けたのが不思議なくらいです。

    有難うございました、助かりました。

    YKsaila


    • 編集済み yksaila 2013年11月5日 13:19
    • 回答としてマーク yksaila 2013年11月5日 13:22
    2013年11月5日 13:14

すべての返信

  • YKsaila さま よろしく。

    何も追加設定していない DataGridView ではご質問文の状況は再現されません。
    恐らく、何か、コードやデザイナで設定・定義なさっているのではないでしょうか?

    Form にひとつ DataGridView を貼り付けて試して見ましたが。 以下コード参照。

    Public Class Form1 Private Sub InitializeDTable() Dim dt As DataTable Dim dr As DataRow 'Create DataTable dt = New DataTable() dt.Columns.Add(New DataColumn("FileName", GetType(String))) dt.Columns.Add(New DataColumn("CreationNow", GetType(Date))) dt.Columns.Add(New DataColumn("CreationNew", GetType(Date))) dr = dt.NewRow() dr(0) = "001.txt" dr(1) = DateTime.Now dr(2) = Format(dr(1), "yyyy/MM/dd HH:mm:ss") dt.Rows.Add(dr) 'DGV DataSource and Setting Me.DataGridView1.DataSource = dt End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load InitializeDTable() End Sub End Class

    2013年11月5日 7:22
  • 状況が今一歩わかりません。新規に追加する行が同時に2行現れるということでしょうか?しかし、それを実現させることは不可能、もしくは簡単ではないと思います。
    想像ですが、1行しか追加させないために何かロジックを組まれていないでしょうか? それが特定の条件下ではうまく動作していないということではないでしょうか?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2013年11月5日 7:29
    モデレータ
  • 確かに、おっしゃる通りだと思います。

    ですので、不要なものを削除しまくり、原因を探求することにしました。

    有難うございました、原因判明と解決策が分かった気がします。 あとで、書き込みます。

    YKsaila

    2013年11月5日 12:56
  • 状況が今一歩わかりません。新規に追加する行が同時に2行現れるということでしょうか?しかし、それを実現させることは不可能、もしくは簡単ではないと思います。
    想像ですが、1行しか追加させないために何かロジックを組まれていないでしょうか? それが特定の条件下ではうまく動作していないということではないでしょうか?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    >新規に追加する行が同時に2行現れるということでしょうか?

    >何かロジックを組まれていないでしょうか? それが特定の条件下ではうまく動作していないということではないでしょうか?

    そうなのです。 ShiroYuki_Motoさんの書き込みからも、よくそれが分かりました。

    それで、いろいろやってみて、うまくいきました! 

    有難うございます、もっと早く相談すれば良かったかもしれないですね。

    以下、解決策です:

    行番号(LineNo)というものを設けています。この番号は、通し番号とは限りません(削除がありますので)。
    この行番号は、プログラム上必須で欠かせません。

    Private Sub DataGridView1_CellClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
    '-----略
    '二行目以降のLineNoに連番を振る(LineNo空白時)。'第一行(e.RowIndex= 0)は入力あるので除外。
    If Me.DataGridView1.CurrentRow.IsNewRow AndAlso e.RowIndex > 0 AndAlso IsDBNull(Me.DataGridView1.CurrentRow.Cells("LineNo").Value) Then  
        'e.RowIndex > 0 → 下記の(e.RowIndex - 1)を負にしないため。
       If Not IsDBNull(Me.DataGridView1.Rows(e.RowIndex - 1).Cells("ItemNo").Value) Then     '前の行のItemNoが空白でないとき
          Me.DataGridView1.CurrentRow.Cells("LineNo").Value = CInt(Me.DataGridView1.Rows(e.RowIndex - 1).Cells("LineNo").Value) + 1  '行番号加算:前行番号 + 1
           Me.DataGridView1.CurrentCell = Me.DataGridView1.Rows(e.RowIndex).Cells("A")
       End If
    End If
    '-----略
    End Sub

    上記のコードが原因でした!
    これを、CellValidated,CellValidatingにもっていっても、同じ現象でした。
    種々の多くの実験を試みましたが、不成功。 この10日間ほど、これに悩まされていました!
    RowValidatingでも、ダメでした。

    コードに問題があるのかもという疑念はあったのですが、確信が持てず、実は他の方法が有るのではと思って投稿しました。

    でも、お二人のご教示により、いろんな部分を削除していき原因探求することにしました。
    ここのFormだけで約4,000行ほどあるのですが、いろんな部分を削除していって、やはり上記のコードに問題があることを突き止めました。
    コード自体に誤りは無いのです。

    要するに:

    新規行をクリックしたときに、ある条件下では、この新規行(New Row)から抜け出せないようにすればよいのですが、これがうまくいっていませんでした。 (以前にも試みましたが、不成功でした。)


    下記のコードを加えました。成功しました!!
    '行への連番付与
     Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
      If Me.DataGridView1.CurrentRow.IsNewRow Then
        If Not IsDBNull(Me.DataGridView1.Rows(e.RowIndex).Cells("LineNo").Value) AndAlso IsDBNull(Me.DataGridView1.Rows(e.RowIndex).Cells("A").Value) Then
           Me.DataGridView1.CurrentCell = Me.DataGridView1.Rows(e.RowIndex).Cells("A")
            e.Cancel = True
        End If
      End If

     End Sub

    これで、成功です!

    新規行Click時に、LineNoをコードで表示します(手入力ではありません)が、その段階で何もせず上の通常行に移行すると新規行のLineNoは消えます(多分、手入力でないから)。 しかし、何かの信号は残っているみたいで、その後に新規行に入力すると複数行の追加に成ります。 これを防ぎたかったのですが、この時、新規行から抜けだせなくするコードがうまく書けていなかったのが原因でした。

    出来てみると何でも簡単に見えます

    10日間も悩み続けたのが不思議なくらいです。

    有難うございました、助かりました。

    YKsaila


    • 編集済み yksaila 2013年11月5日 13:19
    • 回答としてマーク yksaila 2013年11月5日 13:22
    2013年11月5日 13:14