Csharp/CSharp Tutorial/GUI Windows Forms/event
Содержание
- 1 A .NET-compatible event
- 2 Event and event handler
- 3 Events
- 4 Events: add and remove functions
- 5 Events: add and remove functions for a private delegate event
- 6 Events add and remove with synchronized block
- 7 Events and form controls
- 8 Events: Custom Add and Remove with Global delegate cache.
- 9 Fire event in property setter
- 10 Ignored Parameters Anonymous Methods for Button click, kepressed and mouse clicked action
- 11 Use an anonymous method as an event handler
- 12 Use delegate to handle events
- 13 Use the built-in EventHandler delegate
- 14 Using Event Accessors
A .NET-compatible event
<source lang="csharp">using System;
// Derive a class from EventArgs. class MyEventArgs : EventArgs {
public int eventnum;
}
// Declare a delegate for an event. delegate void MyEventHandler(object source, MyEventArgs arg);
// Declare an event class. class MyEvent {
static int count = 0; public event MyEventHandler SomeEvent; // This fires SomeEvent. public void OnSomeEvent() { MyEventArgs arg = new MyEventArgs(); if(SomeEvent != null) { arg.eventnum = count++; Console.WriteLine("Event fired"); SomeEvent(this, arg); } }
}
class X {
public void handler(object source, MyEventArgs arg) { Console.WriteLine("Event " + arg.eventnum + " received by an X object."); Console.WriteLine("Source is " + source); Console.WriteLine(); }
}
class Y {
public void handler(object source, MyEventArgs arg) { Console.WriteLine("Event " + arg.eventnum + " received by a Y object."); Console.WriteLine("Source is " + source); Console.WriteLine(); }
}
class MainClass {
public static void Main() { X ob1 = new X(); Y ob2 = new Y(); MyEvent evt = new MyEvent(); // Add handler() to the event list. evt.SomeEvent += ob1.handler; evt.SomeEvent += ob2.handler; // Fire the event. evt.OnSomeEvent(); evt.OnSomeEvent(); }
}</source>
Event fired Event 0 received by an X object. Source is MyEvent Event 0 received by a Y object. Source is MyEvent Event fired Event 1 received by an X object. Source is MyEvent Event 1 received by a Y object. Source is MyEvent
Event and event handler
<source lang="csharp">using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; class MyClass : IDisposable {
public event EventHandler OnInitialized; public event EventHandler OnDisposed; public void Init() { // Initialize our state... EventHandler onInit = OnInitialized; if (onInit != null) onInit(this, new EventArgs()); } public void Dispose() { // Release our state... EventHandler onDisp = OnDisposed; if (onDisp != null) onDisp(this, new EventArgs()); }
} public class MainClass {
public static void Main(){ using (MyClass f = new MyClass()) { f.OnInitialized += delegate { Console.WriteLine("init"); }; f.OnDisposed += delegate { Console.WriteLine("disposed"); }; f.Init(); } }
}</source>
init disposed
Events
- Event handlers are represented by delegates.
- Events are members of a class
- Events are declared using the event keyword.
Its most commonly used form is shown here:
<source lang="csharp">event event-delegate object;</source>
- event-delegate is the name of the delegate used to support the event.
- object is the name of the specific event object being created.
Events: add and remove functions
<source lang="csharp">using System; public class Button {
public delegate void ClickHandler(object sender, EventArgs e); public event ClickHandler Click; protected void OnClick() { if (Click != null) Click(this, null); } public void DoClick() { OnClick(); }
} class MainClass {
static public void ButtonHandler(object sender, EventArgs e) { Console.WriteLine("Button clicked"); } public static void Main() { Button button = new Button(); button.Click += new Button.ClickHandler(ButtonHandler); button.DoClick(); button.Click -= new Button.ClickHandler(ButtonHandler); button.DoClick(); }
}</source>
Button clicked
Events: add and remove functions for a private delegate event
<source lang="csharp">using System; public class Button {
public delegate void ClickHandler(object sender, EventArgs e); private ClickHandler click; public void AddClick(ClickHandler clickHandler) { click += clickHandler; } public void RemoveClick(ClickHandler clickHandler) { click -= clickHandler; } protected void OnClick() { if (click != null) click(this, null); } public void DoClick() { OnClick(); }
} class MainClass {
static public void ButtonHandler(object sender, EventArgs e) { Console.WriteLine("Button clicked"); } public static void Main() { Button button = new Button(); button.AddClick(new Button.ClickHandler(ButtonHandler)); button.DoClick(); button.RemoveClick(new Button.ClickHandler(ButtonHandler)); button.DoClick(); }
}</source>
Button clicked
Events add and remove with synchronized block
<source lang="csharp">using System; using System.Collections; using System.Runtime.rupilerServices; public class Button {
public delegate void ClickHandler(object sender, EventArgs e); Hashtable delegateStore = new Hashtable(); static object clickEventKey = new object(); public event ClickHandler Click { [MethodImpl(MethodImplOptions.Synchronized)] add { delegateStore[clickEventKey] = Delegate.rubine((Delegate) delegateStore[clickEventKey], value); } [MethodImpl(MethodImplOptions.Synchronized)] remove { delegateStore[clickEventKey] = Delegate.Remove((Delegate) delegateStore[clickEventKey], value); } } protected void OnClick() { ClickHandler ch = (ClickHandler) delegateStore[clickEventKey]; if (ch != null) ch(this, null); } public void DoClick() { OnClick(); }
} class MainClass {
static public void ButtonHandler(object sender, EventArgs e) { Console.WriteLine("Button clicked"); } public static void Main() { Button button = new Button(); button.Click += new Button.ClickHandler(ButtonHandler); button.DoClick(); button.Click -= new Button.ClickHandler(ButtonHandler); button.DoClick(); }
}</source>
Button clicked
Events and form controls
<source lang="csharp">using System; using System.Collections.Generic; using System.ruponentModel; using System.Data; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms;
public class Events : Form { public Events() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("I have been Clicked"); } private void textBox1_MouseEnter(object sender, EventArgs e) { label1.Text = "Mouse Enters into the TextBox"; } private void textBox1_MouseLeave(object sender, EventArgs e) { label1.Text = "Mouse Leaves the TextBox"; } private void textBox1_KeyDown(object sender, KeyEventArgs e) { if (e.Alt == true) label1.Text="The ALT has been pressed"; else if (e.Control==true) label1.Text="The Ctrl has been pressed"; else if (e.Shift==true) label1.Text="The Shift has been pressed"; } private void textBox1_KeyUp(object sender, KeyEventArgs e) { if (e.Alt == false || e.Control==false || e.Shift==false) label1.Text = "The Key has been released"; } private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { if (char.IsDigit(e.KeyChar)==true) label1.Text = "You have pressed a Numeric key"; else if(char.IsLetter(e.KeyChar)==true) label1.Text = "You have pressed a Letter key"; } private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // button1 // this.button1.Location = new System.Drawing.Point(94, 23); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0; this.button1.Text = "Click Me"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(81, 78); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(103, 70); this.textBox1.TabIndex = 1; this.textBox1.MouseLeave += new System.EventHandler(this.textBox1_MouseLeave); this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown); this.textBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyUp); this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress); this.textBox1.MouseEnter += new System.EventHandler(this.textBox1_MouseEnter); // // label1 // this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label1.Location = new System.Drawing.Point(12, 169); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(268, 23); this.label1.TabIndex = 2; this.label1.Text = "label1"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // Events // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292, 273); this.Controls.Add(this.label1); this.Controls.Add(this.textBox1); this.Controls.Add(this.button1); this.Name = "Events"; this.Text = "Events"; this.ResumeLayout(false); this.PerformLayout(); }
private System.Windows.Forms.Button button1; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Label label1; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Events()); } }</source>
Events: Custom Add and Remove with Global delegate cache.
<source lang="csharp">// copyright 2000 Eric Gunnerson // From A Programmer"s Introduction to C# 2.0, Third Edition using System; using System.Collections; using System.Runtime.rupilerServices; // // Global delegate cache. Uses a two-level hashtable. The delegateStore hashtable // stores a hashtable keyed on the object instance, and the instance hashtable is // keyed on the unique key. This allows fast tear-down of the object when it"s destroyed. // public class DelegateCache {
private DelegateCache() {} // nobody can create one of these Hashtable delegateStore = new Hashtable(); // top level hash table static DelegateCache dc = new DelegateCache(); // our single instance Hashtable GetInstanceHash(object instance) { Hashtable instanceHash = (Hashtable) delegateStore[instance]; if (instanceHash == null) { instanceHash = new Hashtable(); delegateStore[instance] = instanceHash; } return(instanceHash); } public static void Combine(Delegate myDelegate, object instance, object key) { lock(instance) { Hashtable instanceHash = dc.GetInstanceHash(instance); instanceHash[key] = Delegate.rubine((Delegate) instanceHash[key], myDelegate); } } public static void Remove(Delegate myDelegate, object instance, object key) { lock(instance) { Hashtable instanceHash = dc.GetInstanceHash(instance); instanceHash[key] = Delegate.Remove((Delegate) instanceHash[key], myDelegate); } } public static Delegate Fetch(object instance, object key) { Hashtable instanceHash = dc.GetInstanceHash(instance); return((Delegate) instanceHash[key]); } public static void ClearDelegates(object instance) { dc.delegateStore.Remove(instance); }
} public class Button {
public void TearDown() { DelegateCache.ClearDelegates(this); } public delegate void ClickHandler(object sender, EventArgs e); static object clickEventKey = new object(); public event ClickHandler Click { add { DelegateCache.rubine(value, this, clickEventKey); } remove { DelegateCache.Remove(value, this, clickEventKey); } } protected void OnClick() { ClickHandler ch = (ClickHandler) DelegateCache.Fetch(this, clickEventKey); if (ch != null) ch(this, null); } public void SimulateClick() { OnClick(); }
} class Test {
static public void ButtonHandler(object sender, EventArgs e) { Console.WriteLine("Button clicked"); } public static void Main() { Button button = new Button(); button.Click += new Button.ClickHandler(ButtonHandler); button.SimulateClick(); button.Click -= new Button.ClickHandler(ButtonHandler); button.TearDown(); }
}</source>
Button clicked
Fire event in property setter
<source lang="csharp">using System; public class SalaryEvent : EventArgs {
public string Message; public SalaryEvent(string message) { this.Message = message; }
} public class Employee {
private int salary; public delegate void SalaryTaxEventHandler( object reactor, SalaryEvent myEvent ); public event SalaryTaxEventHandler OnTax; public int Salary { set { salary = value; if (salary > 1000) { SalaryEvent myEvent = new SalaryEvent("Employee meltdown in progress!"); OnTax(this, myEvent); } } }
} public class EmployeeMonitor {
public EmployeeMonitor(Employee myEmployee) { myEmployee.OnTax += new Employee.SalaryTaxEventHandler(DisplayMessage); } public void DisplayMessage( object myEmployee, SalaryEvent myEvent ) { Console.WriteLine(myEvent.Message); }
}
class MainClass {
public static void Main() { Employee myEmployee = new Employee(); EmployeeMonitor myEmployeeMonitor = new EmployeeMonitor(myEmployee); myEmployee.Salary = 100; myEmployee.Salary = 500; myEmployee.Salary = 2000; }
}</source>
Employee meltdown in progress!
Ignored Parameters Anonymous Methods for Button click, kepressed and mouse clicked action
<source lang="csharp">using System; using System.Windows.Forms; using System.ruponentModel;
class MainClass { static void Main() { Button button = new Button(); button.Text = "Click me"; button.Click += delegate { Console.WriteLine("LogPlain"); }; button.KeyPress += delegate { Console.WriteLine("LogKey"); }; button.MouseClick += delegate { Console.WriteLine("LogMouse"); }; Form form = new Form(); form.AutoSize = true; form.Controls.Add(button); Application.Run(form); } }</source>
Use an anonymous method as an event handler
<source lang="csharp">using System;
delegate void MyEventHandler();
class MyEvent {
public event MyEventHandler SomeEvent; public void OnSomeEvent() { if(SomeEvent != null) SomeEvent(); }
}
class MainClass {
public static void Main() { MyEvent evt = new MyEvent(); // Use an anonymous method as an event handler. evt.SomeEvent += delegate { // This is the event handler. Console.WriteLine("Event received."); }; evt.OnSomeEvent(); evt.OnSomeEvent(); }
}</source>
Event received. Event received.
Use delegate to handle events
<source lang="csharp">using System; public class Button {
public delegate void ClickHandler(object sender, EventArgs e); public ClickHandler Click; protected void OnClick() { if (Click != null) Click(this, null); } public void DoClick() { OnClick(); }
} class MainClass {
static public void ButtonHandler(object sender, EventArgs e) { Console.WriteLine("Button clicked"); } public static void Main() { Button button = new Button(); button.Click = new Button.ClickHandler(ButtonHandler); button.DoClick(); }
}</source>
Button clicked
Use the built-in EventHandler delegate
<source lang="csharp">using System;
// Declare an event class. class MyEvent {
public event EventHandler SomeEvent; // uses EventHandler delegate // This is called to fire SomeEvent. public void OnSomeEvent() { if(SomeEvent != null) SomeEvent(this, EventArgs.Empty); }
}
class MainClass {
static void handler(object source, EventArgs arg) { Console.WriteLine("Event occurred"); Console.WriteLine("Source is " + source); } public static void Main() { MyEvent evt = new MyEvent(); // Add handler() to the event list. evt.SomeEvent += handler; // Fire the event. evt.OnSomeEvent(); }
}</source>
Event occurred Source is MyEvent
Using Event Accessors
- You can use event accessors to take control of the event handler list.
- The accessors specify how the event handler list is implemented.
This form is shown here:
<source lang="csharp">event event-delegate event-name {
add { // code to add an event to the chain } remove { // code to remove an event from the chain } }</source>