Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将EventArgs传递给函数_C#_Winforms_System.drawing - Fatal编程技术网

C# 如何将EventArgs传递给函数

C# 如何将EventArgs传递给函数,c#,winforms,system.drawing,C#,Winforms,System.drawing,我有一个函数,可以将图像绘制到窗体上 private void DrawImage() { OpenFileDialog openfiledialog = new OpenFileDialog(); if (openfiledialog.ShowDialog() == DialogResult.OK) { Bitmap image = (Bitmap)Image.FromFile(openfiledialog.FileName, true);

我有一个函数,可以将图像绘制到窗体上

private void DrawImage()
{
    OpenFileDialog openfiledialog = new OpenFileDialog();
    if (openfiledialog.ShowDialog() == DialogResult.OK)
    {
        Bitmap image = (Bitmap)Image.FromFile(openfiledialog.FileName, true);
        TextureBrush texturebrush = new TextureBrush(image);
        texturebrush.WrapMode = System.Drawing.Drawing2D.WrapMode.Tile;
        Graphics formGraphics = this.CreateGraphics();
        formGraphics.FillRectangle(texturebrush, new RectangleF(90.0F, 110.0F, 00, 300));
        formGraphics.Dispose();
    }
}
但我不会画任何图像,如果我在ButtonClick事件中编写,同样的代码也可以工作

private void button1_Click(object sender, EventArgs e)
{
    //Same code as written in DrawImage()
}
我认为问题在于它需要“事件参数”。我在msdn中读了一些where,但不确定。不知道EventArgs在表单上绘制图像时的作用

是否有任何方法可以实现此功能。

TL;博士 你不必这么做。对于你的情况,忽略它们就行了。然而,它们有时可能有用。阅读完整答案以理解


完整答案 处理事件时,您会收到一个通用的
EventArgs
对象,如果您编写了一个自定义事件,您可能希望收到
EventArgs
的自定义实现

为了简化事情,考虑它是一个保存事件相关数据的基类。< /P> 例如,如果您正在实现一个click事件,如图所示,您将收到两个参数:事件的源和事件相关数据的持有者

有时候这是没用的。和你的样品一样。你不必接受它,也不必使用它。但是,您可以对源数据或事件数据执行一些检查,但这不是代码的目标,因此这两者在这里都是无用的

至于我,我更喜欢将我的方法与事件分开,并从事件中调用它们。我确实将每个事件绑定放在类底部的一个“组”中,以保持所有内容的干净性和可读性。这只是一个建议,您必须找到自己保存代码的方法


为了回答这个问题,以下是两个示例:

1.无用的论据 此示例仅关闭窗体或窗口

public void btn1_Click(object sender, EventArgs e) { Close(); }
2.有用的论据 考虑一个具有某种类型的数据网格的组件,该组件使用所选行的id(PK)触发SelectedRowsChanged事件

// Event declaration. You can, after that, bind it elsewhere.
public event EventHandler<SelectionEventArgs> SelectedRowsChanged;

// This is the local implementation wich will fire the event.
// Here you invoke the event with the selected rows id's.
public void OnSelectedRowsChanged() { if (SelectedRowsChanged != null) CustomSelection(this, new SelectionEventArgs(this.SelectedRows)); }

// This is the custom implementation of the EventArgs to include the
// event-related data (row id)
public class SelectionEventArgs : EventArgs
{
   public int[] SelectedRows{ get; private set; }
   public SelectionEventArgs(int[] selectedRows) { SelectedRows = selectedRows; }
}

// ... then, somewhere else on your code

this.myControl.SelectedRowsChanged += myControl_SelectedRowsChanged;

public void myControl_SelectedRowsChanged(object sender, SelectionEventArgs e)
{
   if (e.SelectedRows.Length > 0) { /* do something */ }
}
您可能有以下几点:

this.button1.Click += (s, e) => { DoSomething(); };
与第一个示例一样,事件参数也存在(
(s,e)
),但它们对于
DoSomething
方法没有用处

Lambda有C#5(.NET 4.5)及以上版本。 有时,在表单构造函数或类似的东西中执行此操作更容易。

TL;博士 你不必这么做。对于你的情况,忽略它们就行了。然而,它们有时可能有用。阅读完整答案以理解


完整答案 处理事件时,您会收到一个通用的
EventArgs
对象,如果您编写了一个自定义事件,您可能希望收到
EventArgs
的自定义实现

为了简化事情,考虑它是一个保存事件相关数据的基类。< /P> 例如,如果您正在实现一个click事件,如图所示,您将收到两个参数:事件的源和事件相关数据的持有者

有时候这是没用的。和你的样品一样。你不必接受它,也不必使用它。但是,您可以对源数据或事件数据执行一些检查,但这不是代码的目标,因此这两者在这里都是无用的

至于我,我更喜欢将我的方法与事件分开,并从事件中调用它们。我确实将每个事件绑定放在类底部的一个“组”中,以保持所有内容的干净性和可读性。这只是一个建议,您必须找到自己保存代码的方法


为了回答这个问题,以下是两个示例:

1.无用的论据 此示例仅关闭窗体或窗口

public void btn1_Click(object sender, EventArgs e) { Close(); }
2.有用的论据 考虑一个具有某种类型的数据网格的组件,该组件使用所选行的id(PK)触发SelectedRowsChanged事件

// Event declaration. You can, after that, bind it elsewhere.
public event EventHandler<SelectionEventArgs> SelectedRowsChanged;

// This is the local implementation wich will fire the event.
// Here you invoke the event with the selected rows id's.
public void OnSelectedRowsChanged() { if (SelectedRowsChanged != null) CustomSelection(this, new SelectionEventArgs(this.SelectedRows)); }

// This is the custom implementation of the EventArgs to include the
// event-related data (row id)
public class SelectionEventArgs : EventArgs
{
   public int[] SelectedRows{ get; private set; }
   public SelectionEventArgs(int[] selectedRows) { SelectedRows = selectedRows; }
}

// ... then, somewhere else on your code

this.myControl.SelectedRowsChanged += myControl_SelectedRowsChanged;

public void myControl_SelectedRowsChanged(object sender, SelectionEventArgs e)
{
   if (e.SelectedRows.Length > 0) { /* do something */ }
}
您可能有以下几点:

this.button1.Click += (s, e) => { DoSomething(); };
与第一个示例一样,事件参数也存在(
(s,e)
),但它们对于
DoSomething
方法没有用处

Lambda有C#5(.NET 4.5)及以上版本。
有时,在表单构造函数或类似的东西中执行此操作更容易。

考虑以下提示来解决此问题:

  • 如果使用
    this.CreateGraphics
    在表单上绘图,则如果表单引用,绘图将消失,例如,如果最小化并还原它。您应该将绘图逻辑放入
    Paint
    事件中

  • 重构方法时,应将
    Graphics
    类型的参数传递给方法,并将其用于绘图。此外,您不应处理传递的参数。您应该将
    Paint
    事件中的
    e.Graphics
    传递给您的方法

  • 在你的方法中,你应该处理你的刷子。使用块将其放入

  • 重构方法时,应该将显示对话框的代码部分移出方法。您应该在不需要在
    Paint
    事件处理程序中调用它

  • 最好不要使用
    Image.FromFile
    加载图像,它会锁定文件,直到图像处理完毕。而是使用
    Image.FromStream

  • 您使用的矩形的
    0
    宽度为
    Width
    。所以,即使使用当前的方法绘制,由于矩形的宽度,也不会看到任何结果

代码

Bitmap image;
private void DrawImage(Bitmap image, Graphics g, Rectangle r)
{
    using (var brush = new TextureBrush(image))
    {
        brush.WrapMode = System.Drawing.Drawing2D.WrapMode.Tile;
        g.FillRectangle(brush, r);
    }
}        

private void button1_Click(object sender, EventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();
    if (dialog.ShowDialog() == DialogResult.OK)
    {
        using (var s = new System.IO.FileStream(dialog.FileName, System.IO.FileMode.Open))
            image = new Bitmap(Image.FromStream(s));

        this.Invalidate();
    }
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    if (image != null)
        this.DrawImage(image, e.Graphics, new RectangleF(10, 10, 200, 200));
}

考虑以下提示来解决问题:

  • 如果使用
    this.CreateGraphics
    在表单上绘图,则如果表单引用,绘图将消失,例如,如果最小化并还原它。您应该将绘图逻辑放入
    Paint
    事件中

  • 重构方法时,应将
    Graphics
    类型的参数传递给方法,并将其用于绘图。此外,您不应处理传递的参数。您应该将
    Paint
    事件中的
    e.Graphics
    传递给您的方法

  • 在你的方法中,你应该处理你的刷子。使用块将其放入

  • 重构方法时,应该将显示对话框的代码部分移出方法。你应该在不需要的时候叫它<