C# Picturebox.Image 需要加载两次才能在代码中使用

C# Picturebox.Image needs to be loaded twice before it can be used in code

我在 windows 表单上有一个图片框,其中填充了此命令:

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

图像加载后,我尝试做两件事,只有在我加载该图像两次后它们才有效。

第一件事:

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

这是做什么的:

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

我要做的第二件事是将图像保存到 SQLDatabase。

cmdLine = "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(cmdLine, connection))
{
//Parameter definieren
   sqlCmd.Parameters.Add("@Image", SqlDbType.Image);
   sqlCmd.Parameters["@Image"].Value = pic;
   sqlCmd.ExecuteNonQuery();
 }

我第二次加载 picturebox.image 后,这两个操作都正确执行了。

是什么原因造成的,我该如何解决?

编辑:

这就是我创建 table 我想将图片保存到:

//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();
}

这就是我从数据库中读取图片的方式:

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;

这不起作用。但是当我在名为 "Bilder" 的数据库中创建一个 table 时,它只有 "Picture" 和 DBType Image 并将代码更改为:

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;

它确实有效。我的原始代码有什么问题?

我在这里混淆了两个问题。

的问题
Positioning.CenterHorizontally(pBProcess, pBProcess.Image.Width);

已通过将此语句放入图片框的 LoadCompleted事件中进行修复。

第二个问题是我实际上在 table(属性 + 值)中插入了很多行,最后我插入了另一行,仅包含图像。当我阅读 table 寻找图像时,我只阅读了第一行(我认为)但没有找到图像。所以我更改了代码,将图像放入第一行,然后更改命令行:

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();
  }
}