在寫WPF教程的MVVM篇章時,會碰到接口INotifyPropertyChanged,裏面只有 一個event PropertyChangedEventHandler PropertyChanged事件,因此引申出本章。
可以在接口中聲明事件,然後在類中實現該事件的引用。在爲方法訂閱事件時,可以訂閱接口聲明的事件,也可以訂閱類中的事件。我們看下面這個例子。
public class CustomEventArgs : EventArgs
{
private double area;
public double Area
{
get { return area; }
set { area = value; }
}
public CustomEventArgs(double a)
{
area = a;
}
}
public interface IDrawingObject
{
event EventHandler<CustomEventArgs> ShapeChanged;//定義一個標準事件
}
public class Shape : IDrawingObject
{
public event EventHandler<CustomEventArgs> ShapeChanged;
public void RaiseEvent()//事件觸發器
{
OnShapeChanged(new CustomEventArgs(10));//觸發事件
}
protected virtual void OnShapeChanged(CustomEventArgs e)
{
if (ShapeChanged != null)
{
ShapeChanged(this, e);
}
}
}
class Program
{
static private void HandlerShapeChanged(object sender,EventArgs e)
{
CustomEventArgs msg=e as CustomEventArgs;
Console.WriteLine(msg.Area);
}
static void Main(string[] args)
{
Shape s = new Shape();
IDrawingObject ido = s;
//爲HandlerShapeChanged方法訂閱接口中聲明的事件
ido.ShapeChanged += HandlerShapeChanged;
//爲HandlerShapeChanged方法訂閱實現接口的事件
//s.ShapeChanged += HandlerShapeChanged;
s.RaiseEvent();
Console.Read();
}
}
我們深挖函數源碼會發現很多地方會用事件訪問器,這裏 不妨順帶研習一下。
事件訪問器類似屬性訪問器,事件訪問器被命名爲add和remove,一般情況下不需提供自定義事件訪問器,因爲在編譯時會自動添加事件訪問器。
1.add事件訪問器:當客戶端訂閱該事件,調用該訪問器。
2.remove事件訪問器:當客戶端取消訂閱事件,調用該訪問器。
我們現在對上面例子進行改造,用add和remove訪問器來刪減事件。Events類來替換Shape類,並且注意入口函數裏的註釋。
public class Events : IDrawingObject
{
public event EventHandler<CustomEventArgs> ShapeChanged;
public event EventHandler<CustomEventArgs> IDrawingObj
{
add
{
ShapeChanged += value;
}
remove
{
try
{
lock (ShapeChanged)//lock對象不能爲null
{
ShapeChanged -= value;
}
}
catch { Console.WriteLine("對象爲null"); }
}
}
public void Raise(CustomEventArgs e)
{
try
{
ShapeChanged(this, e);
}
catch { }
}
}
static void Main(string[] args)
{
Events s = new Events();
s.IDrawingObj += HandlerShapeChanged;
//s.IDrawingObj -= HandlerShapeChanged;//注掉爲ShapeChanged爲null
//s.IDrawingObj -= HandlerShapeChanged;//注掉lock (ShapeChanged)報錯,預先加try{} catch
s.Raise(new CustomEventArgs(10));
Console.Read();
}
總結
接口可以放事件,善於或用藉口和事件,讓代碼更加美觀。