我试图创建一个来自可视化和编辑图像,简单的东西,如:
但我遇到了很多困难,例如:如果我尝试加载的文件不存在或者无法打开(它不是图像),我想显示一个MessageBox,然后关闭表单。 但表单不会立即关闭(这可能会导致错误,因为我可能会尝试访问未打开的文件的属性)。你能告诉我为什么吗? (查看Abort()方法)源代码在帖子的末尾。
我使用以下事件在里面创建我的表单:
private void button2_Click(object sender, EventArgs e)
{
Forms.AreaSelector areaSelector = new Forms.AreaSelector(LabelInput);
areaSelector.ShowDialog();
}
我希望将表单显示为对话框,以便用户无法返回主窗口'没有捕获对图像的修改,这就是为什么我使用.ShowDialog()而不是Show() 我尝试在我的" Abort"中调用Close()甚至Dispose()。方法,但表单继续加载(通过继续加载我的意思是UpdateWindowSize()和UpdatePictureBox()被调用,无论我在Abort()中做什么。)
这是实际的表单代码。
来源:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PeeAlyser.Forms
{
public partial class AreaSelector : Form
{
#region Variables
Bitmap originalImage, modifiedImage;
string fileName;
#endregion
#region Constructors
public AreaSelector(string fileName)
{
InitializeComponent();
this.fileName = fileName;
}
#endregion
private void AreaSelector_Load(object sender, EventArgs e)
{
TryToLoadImage();
UpdateWindowSize();
UpdatePictureBox();
}
#region Private Methods
private void Abort()
{
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.BeginInvoke(new MethodInvoker(this.Close));
//this.Close();
//this.Dispose();
// GODAMNIT!
}
private void TryToLoadImage()
{
if (!System.IO.File.Exists(fileName))
{
MessageBox.Show("File not found.");
Abort();
}
try { originalImage = (Bitmap)Bitmap.FromFile(fileName); }
catch (Exception error)
{
MessageBox.Show("Error: " + Environment.NewLine +
error.ToString());
Abort();
}
this.modifiedImage = new Bitmap(originalImage);
}
private void UpdateWindowSize()
{
int widthDifference = this.Width - pictureBox1.Width;
int heightDifference = this.Height - pictureBox1.Height;
Size windowSize = originalImage.Size;
windowSize.Width += widthDifference;
windowSize.Height += heightDifference;
this.Size = this.MinimumSize = this.MaximumSize = windowSize;
this.pictureBox1.Size = originalImage.Size;
this.AdjustFormScrollbars(true);
}
private void UpdatePictureBox()
{
this.pictureBox1.Image = modifiedImage;
this.Refresh();
}
#endregion
}
}
编辑:我收到很多建议解决它。但汉斯的回答不仅纠正了我的正确设计缺陷(也解决了这个问题),而且还解释了为什么会出现这种问题(查看他的链接)。所以我选择他的答案。 随意关闭这个问题,mods。谢谢你的帮助!
答案 0 :(得分:4)
Load事件在Winforms中过度使用 。它是从它的前身VB6继承的一个挂断,它非常重要,因为它是你放置任何初始化代码的地方。这使它成为默认事件,太容易使用了。
但不是在.NET中,初始化是在类的构造函数中完成的。 Load事件为时已晚,火车离开了火车站并且已经聚集了相当快的速度。试图阻止它是困难的,例如抛出异常没有效果。实际上是very dangerous。只有在需要知道窗口的大小和位置时才应使用Load事件。这很罕见,虽然看起来你有用。
你需要在它开始前停止该列车,你的TryToLoadImage()调用属于构造函数。现在它很简单,当你正常工作的东西无法正常工作时,你可以在C#中做正常的事情,抛出异常。并在ShowDialog()调用站点捕获它。容易腻。
答案 1 :(得分:0)
你可以使TryToLoadImage布尔值(通过返回false替换Adort)并像这样运行它:
if(TryToLoadImage())
{
UpdateWindowSize();
UpdatePictureBox();
}
else Close();
答案 2 :(得分:0)
最好的选择是避免加载事件中的"怀疑部分" 。
但是,如果您想在加载活动本身中执行操作,我建议使用简单程序。
使用名为访问的整数变量,并将其默认设置为 1
如您所述,您希望显示消息框,然后将其关闭。在消息框行之前,将访问变量的值设置为0 。
将post-messagebox代码封装到If-Else块中。
您需要的代码是: -
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PeeAlyser.Forms
{
public partial class AreaSelector : Form
{
#region Variables
Bitmap originalImage, modifiedImage;
string fileName;
#endregion
#region Constructors
public AreaSelector(string fileName)
{
InitializeComponent();
this.fileName = fileName;
}
#endregion
public int access=1;
private void AreaSelector_Load(object sender, EventArgs e)
{
TryToLoadImage();
if(access==1)
{
UpdateWindowSize();
UpdatePictureBox();
}
}
#region Private Methods
private void Abort()
{
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.BeginInvoke(new MethodInvoker(this.Close));
//this.Close();
//this.Dispose();
// GODAMNIT!
}
private void TryToLoadImage()
{
if (!System.IO.File.Exists(fileName))
{
access=0;
MessageBox.Show("File not found.");
Abort();
}
try { originalImage = (Bitmap)Bitmap.FromFile(fileName); }
catch (Exception error)
{
MessageBox.Show("Error: " + Environment.NewLine +
error.ToString());
Abort();
}
this.modifiedImage = new Bitmap(originalImage);
}
private void UpdateWindowSize()
{
int widthDifference = this.Width - pictureBox1.Width;
int heightDifference = this.Height - pictureBox1.Height;
Size windowSize = originalImage.Size;
windowSize.Width += widthDifference;
windowSize.Height += heightDifference;
this.Size = this.MinimumSize = this.MaximumSize = windowSize;
this.pictureBox1.Size = originalImage.Size;
this.AdjustFormScrollbars(true);
}
private void UpdatePictureBox()
{
this.pictureBox1.Image = modifiedImage;
this.Refresh();
}
#endregion
}
}