我是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();
}
}
我以前从未使用过像这样的事件处理程序,所以我有点超出了我的深度。
修改的
抱歉忘了在我的问题上添加更多细节。虽然主要的错误仍然是我的程序不再像以前那样使用这个新代码。我仍然希望捕获的图像显示在我的form1的图片框中。
目前我的事件处理代码有8个错误。在以下代码部分中:
public class ProgressEventArgs : EventArgs
{
public readonly Image { get; private set; }
public ProgressEventArgs( Image img)
{
Image = img;
}
}
我的编译器不喜欢get或set。正如我的compliler声称
无效令牌';'在类,结构或接口成员声明中
然后,在下面的行中,ProgressEventArgs收到以下错误:
预期的类,委托,枚举,接口或结构 但我的想法是它已经在课堂上了。所以我对这个错误感到很困惑。
答案 0 :(得分:1)
看起来你真的需要一本涵盖C#基础知识的书。因为代码中存在各种各样的问题。我们都去过那里 - 只因为你是一位经验丰富的程序员并不意味着你不会因为细微差别而被绊倒。
您的班级有很多static
个成员,但您要在ScreenCapture
中实例化ControlPanel
。我会删除任何static
声明,或者不打算实例化它。
删除静态:
public event StatusUpdateHandler OnUpdateStatus;
public bool saveToClipboard = true;
public void CaptureImage(bool showCursor, Size curSize, // ...
您正在使用using
在bitmap
范围的末尾自动处置using
。由于您希望将其包含在活动中,请先移除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;
如果您要执行实例,则需要在实例化_screenCap后订阅该事件。
_screenCap = new ScreenCapture();
_screenCap.OnUpdateStatus += _screen_CapOnUpdateStatus;
您还需要创建订阅者
_screen_CapOnUpdateStatus(object source, ProgressEventArgs e) {
imagePreview.Image = e.Image;
}
使用您的事件args删除只读。由于private set
,它只能在课堂外阅读。您还需要获得该名称的属性。您可以使用与Type相同的名称,但这可能会导致混淆。考虑使用CapturedImage
。
public Image CapturedImage { get; private set; }
public ProgressEventArgs(Image img)
{
CapturedImage = img;
}
尝试这些更改,然后解决任何剩余的编译器问题。