所以我在填充带有图像的浮动布局面板,使用以下代码:
private void FillPanel(string sql)
{
panel.Controls.Clear();
SQLiteConnection dbConnect = new SQLiteConnection("Data Source=" + dbFullPath + ";Version=3;");
dbConnect.Open();
SQLiteCommand runQuery = new SQLiteCommand(sql, dbConnect);
SQLiteDataReader reader = runQuery.ExecuteReader();
while (reader.Read())
{
PictureBox pB = new PictureBox();
pB.Image = Image.FromFile(reader["imgPath"].ToString());
pB.Size = new Size(100, 100);
pB.SizeMode = PictureBoxSizeMode.StretchImage;
pB.Padding = new Padding();
pB.Margin = new Padding(5,5,5,5);
pB.Name = reader["name"].ToString();
toolTip_Main.SetToolTip(pB, pB.Name);
pB.DoubleClick += img_DoubleClick;
panel.Controls.Add(pB);
}
dbConnect.Close();
}
如果我稍后尝试删除源图片,我会收到错误消息。
" image.png由另一个进程"
使用
要删除我使用以下代码的图像:
private void Delete()
{
foreach (Control x in panel.Controls)
{
if (x is PictureBox)
{
PictureBox pb = x as PictureBox;
string name = pb.Name;
DirectoryInfo pF = new DirectoryInfo(pictureFolder);
foreach (FileInfo file in pF.GetFiles())
{
if(file.Name == name+".png")
{
pb.InitialImage = null;
pb.Dispose();
file.Delete();
break;
}
}
}
}
}
如果我没有用图像填充面板,我可以删除它们。 我只是不知道我还能做些什么呢?" initialimage = null' &安培; 。用于摆脱面板内的图像。
但似乎他们在某处鬼鬼祟祟。
有关于此的任何想法吗?
答案 0 :(得分:2)
打开图像时要记住的基本规则是:
Image
对象,防止文件被覆盖或删除,直到图像被丢弃。Image
对象。与文件不同,没有任何主动强制执行这一点,但在关闭流后,图像在保存,克隆或以其他方式操纵时会出错。(如果您想知道,Image.FromFile(String filename)
实际上只是new Bitmap(String filename)
构造函数的包装器。我个人建议不要使用Image.FromFile
,因为它会丢失更精确的Bitmap
PictureBox
1}}返回对象的类型。)
至于您的问题,似乎处置pb.Image
并未处理实际图像。这可以通过首先明确处理Image img = pb.Image;
// Needs to happen in this order so the UI will never try to paint the disposed image
pb.Image = null;
if (img != null)
img.Dispose();
file.Delete();
break;
来解决:
new Bitmap(Image image)
请注意,处理实际的图像框可能会导致问题;你应该首先从它的父控件中删除它,这样它就不再显示在UI上,否则你的表单将开始抛出" object dispos"例外,因为它试图绘制的控件之一无效。
解决锁定问题的另一种方法是从磁盘读取位图,使用using
构造函数从中创建新的位图,然后处理从文件初始化的位图对象。执行此操作的最佳方法是使用using (Bitmap im = new Bitmap(reader["imgPath"].ToString()))
pB.Image = new Bitmap(im);
指令,如下所示:
Function ExtractCap(Txt As String) As String
Application.Volatile
Dim i As Long
For i = 1 To Len(Txt)
Select Case Asc(Mid(Txt, i, 1))
Case 65 To 90
ExtractCap = ExtractCap & Mid(Txt, i, 1)
End Select
Next
End Function
通常,您应该始终清理您创建的图像对象。请注意,这实际上会在新的32bppARGB图像上绘制图像,从而丢失图像的原始格式。虽然在你的情况下,我认为这并不重要,因为它只是用于在UI上显示。 (注意,如果您确实需要图像的完整1:1数据克隆而没有任何指向流或文件的链接,则有办法执行此操作,但they're slightly more advanced。)