我是Winforms中使用事件处理程序的新手。
我想做的是用鼠标对我的桌面进行屏幕截图,指定要捕捉的区域,然后将此图像显示在图片中。有人建议我在另一篇文章中使用事件处理程序来完成这项工作,但我在尝试实现这一点时遇到了真正的问题。有人能看看我做了什么,告诉我我做错了什么吗?
如果做不到,就给我指明正确的方向来解决这个问题?
首先,我的屏幕捕获代码:
class ScreenCapture
{
public delegate void StatusUpdateHandler(object sender, ProgressEventArgs e);
public static event StatusUpdateHandler OnUpdateStatus;
public static bool saveToClipboard = true;
public static void CaptureImage(bool showCursor, Size curSize, Point curPos, Point SourcePoint, Point DestinationPoint, Rectangle SelectionRectangle, string FilePath, string extension)
{
using (Bitmap bitmap = new Bitmap(SelectionRectangle.Width, SelectionRectangle.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(SourcePoint, DestinationPoint, SelectionRectangle.Size);
if (showCursor)
{
Rectangle cursorBounds = new Rectangle(curPos, curSize);
Cursors.Default.Draw(g, cursorBounds);
}
}
if (saveToClipboard)
{
Image img = (Image)bitmap;
Clipboard.SetImage(img);
if (OnUpdateStatus == null) return;
ProgressEventArgs args = new ProgressEventArgs(img);
OnUpdateStatus(this,args);
// this is where the screen capture is stored.
// it is this image I want pass to the image box
}
else
{
switch (extension)
{
case ".bmp":
bitmap.Save(FilePath, ImageFormat.Bmp);
break;
case ".jpg":
bitmap.Save(FilePath, ImageFormat.Jpeg);
break;
case ".gif":
bitmap.Save(FilePath, ImageFormat.Gif);
break;
case ".tiff":
bitmap.Save(FilePath, ImageFormat.Tiff);
break;
case ".png":
bitmap.Save(FilePath, ImageFormat.Png);
break;
default:
bitmap.Save(FilePath, ImageFormat.Jpeg);
break;
}
}
}
}
}
public class ProgressEventArgs : EventArgs
{
public Image { get; private set; }
public ProgressEventArgs( Image img)
{
Image = img;
}
}
我的form1类中的代码:
public partial class ControlPanel : Form
{
public EventHandler<ScreenCapture> capture;
private ScreenCapture _screenCap;
public ControlPanel()
{
InitializeComponent();
_screenCap = new ScreenCapture();
_screenCap.OnUpdateStatus += new ScreenCapture.StatusUpdateHandler(SetImage);
}
private void SetImage(object sender, ProgressEventArgs e)
{
// the image box I want the image to be passed to
// imagePreview.Image = e.OnUpdateStatus;
SetImage(e.Image);
}
private void btn_CaptureArea_Click(object sender, EventArgs e)
{
this.Hide();
Form1 form1 = new Form1();
form1.InstanceRef = this;
form1.Show();
}
}
我以前从未使用过这样的事件处理程序,所以我有点力不从心。
编辑
抱歉,忘记为我的问题添加更多详细信息。尽管主要的错误仍然是我的程序不再像以前使用这个新代码那样工作。我仍然希望捕获的图像显示在我的表单1中的图片框中。
目前,我的事件处理代码有8个错误。在以下代码部分:
public class ProgressEventArgs : EventArgs
{
public readonly Image { get; private set; }
public ProgressEventArgs( Image img)
{
Image = img;
}
}
我的编译器不喜欢get或set。正如我的同谋声称
无效的令牌";"在类、结构或接口成员声明中
然后,在下面的行中,ProgressEventArgs得到以下错误:
应为类、委托、枚举、接口或结构但我的想法是,它已经在课堂上了。所以我真的被这个错误弄糊涂了。
你似乎真的需要一本涵盖C#基础知识的书。因为代码中分散着各种各样的问题。我们都去过那里——仅仅因为你是一个经验丰富的程序员并不意味着你不会被细微差别绊倒。
屏幕捕获
您的类有许多static
成员,但您正在ControlPanel
中实例化ScreenCapture
。我会删除任何static
声明,或者不必实例化它
移除静态:
public event StatusUpdateHandler OnUpdateStatus;
public bool saveToClipboard = true;
public void CaptureImage(bool showCursor, Size curSize, // ...
您正在使用using
自动处理using
作用域末尾的bitmap
。既然要将其包含在事件中,请删除第一个using
。
Bitmap bitmap = new Bitmap(SelectionRectangle.Width, SelectionRectangle.Height);
using (Graphics g = Graphics.FromImage(bitmap)) { // ...
既然bitmap
不会被处理,您可以在CaptureImage
函数的末尾添加触发事件的代码。
if (OnUpdateStatus != null) {
OnUpdateState(this, ProgressEventArgs(img));
}
控制面板
如果保持ScreenCapture
静态,则不要创建实例,并在类上注册事件。
// _screenCap = new ScreenCapture();
ScreenCapture.OnUpdateStatus += _screen_CapOnUpdateStatus;
如果要执行实例,则需要在_screenMap实例化后订阅该事件。
_screenCap = new ScreenCapture();
_screenCap.OnUpdateStatus += _screen_CapOnUpdateStatus;
你需要创建订户太
_screen_CapOnUpdateStatus(object source, ProgressEventArgs e) {
imagePreview.Image = e.Image;
}
ProgressEventArgs
使用事件参数删除只读。由于private set
,它将在类外只读。您还需要为属性获取一个名称。您可以使用与类型相同的名称,但这可能会造成混淆。考虑使用CapturedImage
。
public Image CapturedImage { get; private set; }
public ProgressEventArgs(Image img)
{
CapturedImage = img;
}
请尝试这些更改,然后解决任何剩余的编译器问题。