2016-06-28 9 views
1

最初にオフにしてください - ここにあるすべての情報とスニペットに感謝します。感謝します。私の問題;GDIでの一般的なエラー+画像付きのDatagridviewデータをXMLに保存

イメージを含むいくつかのdatagridviewデータをXMLファイルに保存しようとしています。その後、再びグリッドでそれを読み取ろうとしています。私はデータセット&テーブル(無制限)を使用して、私が知っている限りXMLを簡単に書くことができます。バインディングはimagecolumnで動作しません。

データを保存してからもう一度読むことができます。しかし - とき、私は再びデータを保存しよう - それは「サブSaveToFileメソッド」に次の行に失敗し、次のエラーで

Img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg) 

An unhandled exception of type System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll Additional information: A generic error occurred in GDI+.

すべてのアイデアは、私は何が欠けていますか?

Private Sub SaveToFile(sender As Object, e As EventArgs) Handles SaveToolStripMenuItem.Click 
    Dim rows As Integer = DataGridView1.Rows.Count - 1 
    Dim cols As Integer = DataGridView1.Columns.Count - 1 
    Dim MyByte As Byte() = Nothing 
    Dim Img As Image = Nothing 
    Dim ms = New MemoryStream() 
    DataSet1.Observations.Rows.Clear() 

    For i = 0 To rows 
     For j = 0 To cols 
      If j = 0 Then 
       Img = DataGridView1.Rows(i).Cells(j).Value 
       Img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg) 
       MyByte = ms.ToArray() 
       DataSet1.Observations.Rows.Add.Item(1) = Compress(MyByte) 
       ms.close() 
      ElseIf j >= 1 Then 
       If DataGridView1.Rows(i).Cells(j).Value IsNot Nothing Then 
        DataSet1.Observations.Rows(i).Item(j + 1) = DataGridView1.Rows(i).Cells(j).Value.ToString 
       End If 
      End If 
     Next 
    Next 
    File.Delete("C:\test2.quad") 
    DataSet1.WriteXml("C:\test2.quad") 
End Sub 
Private Sub OpenFile(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click 

    Dim ms = New MemoryStream() 
    Dim MyByte As Byte() 

    DataSet1.Clear() 
    DataGridView1.Rows.Clear() 
    DataSet1.ReadXml("C:\test2.quad") 
    Dim rows As Integer = DataSet1.Observations.Rows.Count - 2 
    Dim cols As Integer = DataSet1.Observations.Columns.Count - 1 

    For i = 0 To rows 
     For j = 1 To cols 
      If j = 1 Then 
       MyByte = Decompress(DataSet1.Observations.Rows(i).Item(1)) 
       Dim stream As New MemoryStream(MyByte) 
       DataGridView1.Rows.Add(Image.FromStream(stream)) 
       stream.Close() 
      ElseIf j >= 2 And DataSet1.Observations.Rows(i).Item(j) IsNot Nothing Then 
       DataGridView1.Rows(i).Cells(j - 1).Value = DataSet1.Observations.Rows(i).Item(j).ToString 
      End If 
     Next 
    Next 


End Sub 
+0

作業している行の数はいくつですか? – Plutonix

+0

InternalExceptionがありますか?もしあれば、それは何と言いますか? –

+2

@AlexB。その例外にはこれ以上何も言えません。ファイルアクセスの問題からリソースを超過するまで、それはすべてのものを捕まえるものです。実際に 'GDIでジェネリックエラーが発生しました' *は追加情報です – Plutonix

答えて

0

このエラーは、ファイルアクセスが拒否されてからリソースがなくなるまでのすべてを含むcatch-allです。この場合は同じMemoryStreamを何度も再利用しているからです。

しかし、画像を手動で変換して圧縮する必要はありません。 DataTableByte()列がある場合、DataGridViewは、それをイメージとして使用するために変換する方法を知っています。また、WriteXMLメソッドは自動的にバイトをBase64文字列としてエンコードします(読み戻す)。

サンプル:

Dim dtX = New DataTable("dtX") 

Dim imgs As Image() = {My.Resources.ballblack, My.Resources.ballblue, 
       My.Resources.ballgreen, My.Resources.ballorange, 
       My.Resources.ballpurple, My.Resources.ballred, 
       My.Resources.ballyellow} 

' columns to use 
dtX.Columns.Add(New DataColumn("Name", GetType(String))) 
dtX.Columns.Add(New DataColumn("Descr", GetType(String))) 
dtX.Columns.Add(New DataColumn("Img", GetType(Byte()))) 

Dim dr As DataRow 
Dim g As Int32 
For n As Int32 = 0 To 9 
    dr = dtX.NewRow 

    dr(0) = RD.GetNames(2) 
    dr(1) = RD.GetLorem(40) 
    g = RNG.Next(0, 7)   ' pick random index 
    Using ms As New MemoryStream 
     imgs(g).Save(ms, ImageFormat.Png) 
     dr(2) = ms.ToArray() 
    End Using 

    dtX.Rows.Add(dr) 
Next 

' "Before" 
dgv1.DataSource = dtX 
' save to XML 
dtX.WriteXml("C:\Temp\DTX.xml", XmlWriteMode.WriteSchema) 
  • RDは単なるランダムデータ発生器です。それを無視します。
  • XmlWriteMode.WriteSchemaは、が非常に重要です。です。データを読み取るときに、宛先DataTableが、iVBORw0KGgoAAAANSUhEUgAAABA...
  • を表示するのではなく、そのBase64文字列をByteアレイに変換することを知りたい場合は、Usingブロックにも注意してください。これにより、最後にMemoryStreamが破棄され、割り当てられたリソースを解放することができます。これは、、コードに欠けていると、結果としてのMemoryStreamが漏れに加えて、データを蓄積している:私は非常に小さい画像に同じものを使用している場合
    • 、ストリームのサイズは334, 684, 1014, 1361...を報告します。画像データが蓄積されていて、最初の画像を除くすべてが壊れてGDIエラーが発生します。

往復をテストするためのコード:

Dim dtXYZ = New DataTable() 

' or use a dataset 
dtXYZ.ReadXml("C:\Temp\DTX.xml") 
dgv1.DataSource = dtXYZ 

enter image description here

前と後の両方に同じデータを。

+0

私はそこになかった問題を修正しています。テストして、あなたに戻ってくるだろう。 –

+0

ありがとうございました。 –

関連する問題