2016-03-20 6 views
1
im Code verwendet werden kann

Ich habe einen picturebox auf einem Windows-Formular, das mit diesem Befehl gefüllt wird:C# braucht Picturebox.Image zweimal geladen werden, bevor es

pBProcess.ImageLocation = Path.GetDirectoryName(processFile) + "\\" + processes[processStep2Nr] + ".png"; 

Nachdem die Bilder geladen Ich versuche, zwei Dinge zu tun, die beide nur funktionieren, nachdem ich das Bild zweimal geladen habe.

Erste Sache:

Positioning.CenterHorizontally(pBProcess, pBProcess.Image.Width); 

Was dies bedeutet:

public static void CenterHorizontally(this Control control, int Width) 
{ 
    Rectangle parentRect = control.Parent.ClientRectangle; 
    control.Left = (parentRect.Width - Width)/2; 
} 

und das zweite, was ich versuche zu tun, um das Bild zu einem SQLDatabase zu speichern.

Beide Aktionen werden korrekt ausgeführt, nachdem ich die picturebox.image ein zweites Mal geladen habe.

Was verursacht dies und wie kann ich es beheben?

Edit:

Dies ist, wie ich die Tabelle erstellen Ich möchte das Bild speichern:

//Tabelle wird erstellt und anschließend gefüllt 
strInsert = "CREATE TABLE " + processToSave + "(Attributes NVARCHAR(50), Value TINYINT, Picture IMAGE);"; 
using (SqlCommand sqlCmd = new SqlCommand(strInsert, connection)) 
{ 
    sqlCmd.ExecuteNonQuery(); 
} 
strInsert = "INSERT INTO " + processToSave + " (Attributes, Value) VALUES (@Attributes, @Value);"; 
foreach (ListViewItem item in checkedItems) 
{ 
    using (SqlCommand sqlCmd = new SqlCommand(strInsert, connection)) 
    { 
     //Parameter definieren 
     sqlCmd.Parameters.Add("@Attributes", SqlDbType.NVarChar); 
     sqlCmd.Parameters["@Attributes"].Value = item.Text; 
     sqlCmd.Parameters.Add("@Value", SqlDbType.Int); 
     sqlCmd.Parameters["@Value"].Value = Convert.ToInt32(item.SubItems[1].Text); 
     sqlCmd.ExecuteNonQuery(); 
    } 
} 
strInsert = "INSERT INTO " + processToSave + " (Picture) VALUES (@Image);"; 
MemoryStream stream = new MemoryStream(); 
pBProcess.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
byte[] pic = stream.ToArray(); 
using (SqlCommand sqlCmd = new SqlCommand(strInsert, connection)) 
{ 
    //Parameter definieren 
    sqlCmd.Parameters.Add("@Image", SqlDbType.Image); 
    sqlCmd.Parameters["@Image"].Value = pic; 
    sqlCmd.ExecuteNonQuery(); 
} 

Und das ist, wie ich das Bild von der DB lesen:

MemoryStream stream = new MemoryStream(); 
strInsert = "SELECT [Picture] FROM " + processToLoad; 
SqlCommand sqlCmd2 = new SqlCommand(strInsert, connection); 
byte[] image = (byte[])sqlCmd2.ExecuteScalar(); 
stream.Write(image, 0, image.Length); 
Bitmap bitmap = new Bitmap(stream); 
pBProcess.Image = bitmap; 

das funktioniert nicht. Aber wenn ich eine Tabelle in der DB als „Bilder“ erstellen, die nur „Bild“ mit DBType Bild hat und ändern Sie den Code dazu:

strInsert = "INSERT INTO Bilder (Picture) VALUES (@Image);"; 
MemoryStream stream = new MemoryStream(); 
pBProcess.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
byte[] pic = stream.ToArray(); 
using (SqlCommand sqlCmd = new SqlCommand(strInsert, connection)) 
{ 
    //Parameter definieren 
    sqlCmd.Parameters.Add("@Image", SqlDbType.Image); 
    sqlCmd.Parameters["@Image"].Value = pic; 
    sqlCmd.ExecuteNonQuery(); 
} 

... 

MemoryStream stream = new MemoryStream(); 
strInsert = "SELECT [Picture] FROM Bilder"; 
SqlCommand sqlCmd2 = new SqlCommand(strInsert, connection); 
byte[] image = (byte[])sqlCmd2.ExecuteScalar(); 
stream.Write(image, 0, image.Length); 
Bitmap bitmap = new Bitmap(stream); 
pBProcess.Image = bitmap; 

Es funktioniert tatsächlich. Was ist falsch in meinem ursprünglichen Code?

+0

Laden Sie möglicherweise außerhalb des UI-Threads? – TaW

+0

Es ist Teil eines SelectionChangeCommitted Ereignisses einer Combobox – Stef

+0

Hm, vielleicht warten Sie noch auf 'LoadCompleted'? – TaW

Antwort

0

Ich vermischte hier zwei Probleme.

Das Problem mit

Positioning.CenterHorizontally(pBProcess, pBProcess.Image.Width); 

wurde, indem man diese Aussage in die LoadCompleted Ereignis des picturebox fixiert.

Das zweite Problem war, dass ich tatsächlich viele Zeilen in meine Tabelle (Attribute + Wert) eingefügt und am Ende habe ich eine andere Zeile eingefügt, nur aus dem Bild besteht. Als ich den Tisch las, um nach dem Bild zu suchen, las ich nur die erste Zeile (glaube ich), aber es gab kein Bild. Also habe ich den Code in der ersten Zeile geändert und dann die Befehlszeile geändert:

bool first = true; 
foreach (ListViewItem item in checkedItems) 
{ 
    if (first) 
    cmdLine = "INSERT INTO " + processToSave + " (Attributes, Value, Picture) VALUES (@Attributes, @Value, @Image);"; 
    else 
    cmdLine = "INSERT INTO " + processToSave + " (Attributes, Value) VALUES (@Attributes, @Value);"; 
    using (SqlCommand sqlCmd = new SqlCommand(cmdLine, connection)) 
    { 
    //Parameter definieren 
    sqlCmd.Parameters.Add("@Attributes", SqlDbType.NVarChar); 
    sqlCmd.Parameters["@Attributes"].Value = item.Text; 
    sqlCmd.Parameters.Add("@Value", SqlDbType.Int); 
    sqlCmd.Parameters["@Value"].Value = Convert.ToInt32(item.SubItems[1].Text); 
    if (first) 
    { 
     sqlCmd.Parameters.Add("@Image", SqlDbType.Image); 
     sqlCmd.Parameters["@Image"].Value = pic; 
     first = false; 
    } 
    sqlCmd.ExecuteNonQuery(); 
    } 
}