基本GUI事件处理问题C#

基本GUI事件处理问题C#,c#,events,user-interface,event-handling,C#,Events,User Interface,Event Handling,下午好 我有一些关于GUI事件处理的基本问题。首先,使用C#我们如何将事件链接到对象-我猜是事件处理程序?如果是,每个处理程序是否可以使用单独的代码事件处理程序如何定位它必须操作的对象 我大致了解它在JAVA中的工作原理。给我指一个参考资料就可以了——我已经在谷歌搜索过了,但没有找到任何答案 非常感谢,, J在VisualStudio中使用designer,您将可以轻松地使用GUI对象处理程序。单击“lightning”按钮,您将看到部分控件的所有可用事件。通过在所选事件上单击两次,IDE将为您

下午好

我有一些关于GUI事件处理的基本问题。首先,使用C#我们如何将事件链接到对象-我猜是事件处理程序?如果是,每个处理程序是否可以使用单独的代码事件处理程序如何定位它必须操作的对象

我大致了解它在JAVA中的工作原理。给我指一个参考资料就可以了——我已经在谷歌搜索过了,但没有找到任何答案

非常感谢,,
J

在VisualStudio中使用designer,您将可以轻松地使用GUI对象处理程序。单击“lightning”按钮,您将看到部分控件的所有可用事件。通过在所选事件上单击两次,IDE将为您生成一个方法存根

    private void button_Click(object sender, EventArgs e)
    {
        //sender is the object which actually raised the event
        ((Button)sender).Text = "Clicked Me";
    }
事件处理程序是这样添加的(在*.Designer.cs文件中自动完成)


每个事件实际上都是一个委托-使用以下符号向该委托注册事件处理程序:

myButton.Click += new EventHandler(myEventHandler);
这样,当按钮单击事件激发时,其调用列表上的任何事件处理程序(在本例中,这将包括
myEventHandler
函数)

对于每个按钮,您都执行相同的操作,并注册要触发的事件处理程序(对于多个按钮,可以是相同的事件处理程序)


这个MSDN主题可能会有一些启发:。

这取决于您使用的UI库。在WPF中,您可以在XAML中定义事件处理程序:

<Button Click="HelloWorldClickEventHandler">Hello World</Button>

// this is in your .cs code file
private void HelloWorldClickEventHandler(object sender, RoutedEventArgs e)
{
    // some code
}
当然,使用像VisualStudio这样的IDE可以大大简化这个过程

事件处理程序如何定位它必须操作的对象

有两种方法可以访问相关对象:

  • 由于这些方法是窗口(WPF)或窗体(WinForms)的实例方法,因此它们可以直接访问所有UI资源(即,您可以在代码中使用
    this.MyLabel

  • 第一个参数,
    sender
    ,按照惯例是引发事件的UI控件。如果您对多个UI控件使用一个事件处理程序,这将非常有用

首先是C#我们如何将事件联系起来 到对象-我在猜测事件 处理程序?如果是,每个处理程序可以使用 单独代码

是的,每个事件处理程序都可以有自己的代码:

class A {
    public event EventHandler SomeEvent;
}

class B {
    public B(A a) {
        a.SomeEvent += (sender, e) => { Console.WriteLine("B's handler"); };
    }
}

class C {
    public C(A a) {
        a.SomeEvent += (sender, e) => { Console.WriteLine("C's handler"); };
    }
}
事件处理程序如何定位 它必须操纵的对象

我将对此进行过度简化,但事件处理程序本质上是观察者模式的包装器。事件处理程序与任何其他委托类型一样,在方法调用列表中持有订阅者列表(请参阅)。您可以这样认为:

class EventHandler {
    LinkedList<Action<object, EventArgs>> subscribers =
        new LinkedList<Action<object, EventArgs>>();

    public void Add(Action<object, EventArgs> f) {
        subscribers.AddLast(f);
    }

    public void Remove(Action<object, EventArgs> f) {
        subscribers.Remove(f);
    }

    public void Invoke(object sender, EventArgs e) {
        foreach(Action<object, EventArgs> f in subscribers)
            f(sender, e);
    }
}
类事件处理程序{
LinkedList订户=
新建LinkedList();
公共无效添加(操作f){
订阅者。AddLast(f);
}
移除公共空间(行动f){
删除(f);
}
公共void调用(对象发送方、事件参数){
foreach(订阅服务器中的操作f)
f(发送者,e);
}
}
(上面的代码与实际事件处理程序类的实际实现细节相去甚远。委托类型是不可变的,因此添加处理程序会返回添加了处理程序的新委托,而不是修改处理程序。我相信他们的Add/Remove方法中也有很多线程巫术。)

由于委托实例持有对其每个订户的引用,因此它可以直接访问它所操纵的任何对象

class A {
    public event EventHandler SomeEvent;
}

class B {
    public B(A a) {
        a.SomeEvent += (sender, e) => { Console.WriteLine("B's handler"); };
    }
}

class C {
    public C(A a) {
        a.SomeEvent += (sender, e) => { Console.WriteLine("C's handler"); };
    }
}
class EventHandler {
    LinkedList<Action<object, EventArgs>> subscribers =
        new LinkedList<Action<object, EventArgs>>();

    public void Add(Action<object, EventArgs> f) {
        subscribers.AddLast(f);
    }

    public void Remove(Action<object, EventArgs> f) {
        subscribers.Remove(f);
    }

    public void Invoke(object sender, EventArgs e) {
        foreach(Action<object, EventArgs> f in subscribers)
            f(sender, e);
    }
}