日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#委托及事件

發布時間:2025/3/15 C# 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#委托及事件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://blog.csdn.net/xingmyworld/article/details/6764244

C#中,委托(delegate)是一種引用類型,在其他語言中,與委托最接近的是函數指針,但委托不僅存儲對方法入口點的引用,還存儲對用于調用方法的對象實例的引用。

簡單的講委托(delegate)是一種類型安全的函數指針,首先,看下面的示例程序,在C++中使用函數指針。

首先,存在兩個方法:分別用于求兩個數的最大值和最小值。

int Max(int x,int y)

{

return x>y?x:y;

}

int Min(int x,int y)

{

return x

}

上面兩個函數的特點是:函數的返回值類型及參數列表都一樣。那么,我們可以使用函數指針來指代這兩個函數,并且可以將具體的指代過程交給用戶,這樣,可以減少用戶判斷的次數。

下面我們可以建立一個函數指針,將指向任意一個方法,代碼如下所示:

//定義一個函數指針,并聲明該指針可以指向的函數的返回值為int類型,參數列表中包//括兩個int類型的參數

int (*p)(int,int);

//讓指針p指向Max函數

p=max;

//利用指針調用Max

c=(*p)(5,6);

我們的問題在于,上面的代碼中,為什么不直接使用Max函數,而是利用一個指針指向Max之后,再利用指針調用Max函數呢?

實際上,使用指針的方便之處就在于,當前時刻可以讓指針p指向Max,在后面的代碼中,我們還可以利用指針p再指向Min函數,但是不論p指向的是誰,調用p時的形式都一樣,這樣可以很大程度上減少判斷語句的使用,使代碼的可讀性增強!

C#中,我們可以使用委托(delegate)來實現函數指針的功能,也就是說,我們可以像使用函數指針一樣,在運行時利用delegate動態指向具備相同簽名的方法(所謂的方法簽名,是指一個方法的返回值類型及其參數列表的類型)。

6.1使用委托(delegate

6.1.1委托的建立

建立委托(delegate),過程有點類似于建立一個函數指針。過程如下:

1.建立一個委托類型,并聲明該委托可以指向的方法的簽名(函數原型)

delegate void MyDelegate(int a,int b);

2.建立一個委托類的實例,并指向要調用的方法

//利用委托類的構造方法指定,這是最為常見的一種方式

MyDelegate md=new MyDelegate(Max);

//利用自動推斷方式來指明要調用的方法,該形式更類型于函數指針

MyDelegate md=Max;

3.利用委托類實例調用所指向的方法

int c=md(4,5);

下面通過實例來演示C#中委托的使用。

l????????案例操作020601:利用委托實現方法的動態調用

首先,添加如下控件:

Ø?兩個RadioButton,分別用來讓用戶選擇求最大值以及求最小值

Ø?二個TextBox,用來輸入兩個操作數

Ø?一個TextBox,用來顯示運算結果

Ø?一個Button,用來執行運算

界面如下圖所示:

下一步,在窗口中添加兩個方法:MaxMin,這兩方法的代碼如下:

int Max(int x,int y)

{

return x>y?x:y;

}

int Min(int x,int y)

{

return x

}

窗口中的代碼,如下圖所示:

下一步:為了使用委托來實現動態指向,我們需要建立一個委托類“MyDelegate”,并建立該委托類型的一個實例,如下圖所示:

上面的代碼中,我們可以發現,此時,還沒有讓MyDelegate類型的實例“md”指向任何一個方法(即:md的值為null),原因是:在編寫代碼的時候,我們還不知道用戶想要調用哪一個方法。

下一步,分別為兩個RadioButton編寫它們的“CheckedChanged”事件,代碼如下:

private void rbtMax_CheckedChanged(object sender, EventArgs e)

{

??? if (this.rbtMax .Checked ==true)

??? {

??????? this.md = new MyDelegate(this.Max );

??? }

}

?

private void rbtMin_CheckedChanged(object sender, EventArgs e)

{

??? if (this.rbtMin .Checked ==true)

??? {

??????? this.md = new MyDelegate(this.Min );

???}

}

這段代碼是,如果用戶選擇了求最大值的RadioButton,則讓MyDelegate類型的實例“md”指向Max方法,如果用戶選擇了求最小值的RadioButton,則讓MyDelegate類型的實例“md”指向Min方法。這樣作的目的,就是要把選擇的過程交給用戶。

下一步,我們為界面中的Button編寫Click事件,并利用委托來調用求最值的方法。代碼如下所示:

private void btGetResult_Click(object sender, EventArgs e)

{

??? if (this.md ==null )

??? {

??????? MessageBox.Show("委托md沒有指向任何方法!");

??????? return;

??? }

??? int a = int.Parse(this.tbxOP1 .Text );

??? int b = int.Parse(this.tbxOP2 .Text );

??? int c = this.md(a,b);

??? this.tbxResult.Text = c.ToString();

}

從上面的代碼中,可以發現,在使用委托之前,先要判斷其值是否為空,如果不為空,則可以進行調用,同時,使用者可以看到,在調用md時,我們并沒有關心md到底指向了哪一個方法,總之,md不為空的時候,就一定會指向MaxMin當中的一個。

為了讓求最大值的RadioButton在程序開始運行的時候就被選中,在FormLoad事件中添加如下代碼:

private void Form1_Load(object sender, EventArgs e)

{

??? this.md = new MyDelegate(this.Max );

}

運行的效果如下圖所示:

求最大值

求最小值

l????????委托使用的注意事項

Ø??在C#中,所有的委托都是從System.MulticastDelegate類派生的。

Ø??委托隱含具有sealed屬性,即不能用來派生新的類型。

Ø??委托最大的作用就是為類的事件綁定事件處理程序。

Ø??在通過委托調用函數前,必須先檢查委托是否為空(null),若非空,才能調用函數。

Ø??在委托實例中可以封裝靜態的方法也可以封裝實例方法。

Ø??在創建委托實例時,需要傳遞將要映射的方法或其他委托實例以指明委托將要封裝的函數原型(.NET中稱為方法簽名:signature)。注意,如果映射的是靜態方法,傳遞的參數應該是類名.方法名,如果映射的是實例方法,傳遞的參數應該是實例名.方法名。

Ø??只有當兩個委托實例所映射的方法以及該方法所屬的對象都相同時,才認為它們是想等的(從函數地址考慮)。

?

6.1.2討論委托類型

從上面的案例中,我們可以發現,在使用委托之前,先要定義一個委托類型,如下所示:

delegate int MyDelegate(int a, int b);

MyDelegate md = null;

既然叫做委托類型,就說明MyDelegate實際上是一個類,上面的寫法只是一種簡單的縮略寫法,實際上,我們自己定義的委托,都是繼承自System.MulticastDelegate類的,但是我們確不能自己定義一個類去繼承自System.MulticastDelegate類,為了證明這點,我們可以使用ildasm工具,來查看“MyDelegate”的IL代碼。

首先在Visual Studio控制臺,如下圖所示:

在打開的“Visual Studio2008 Command Prompt”窗口中,輸入ildam,如下圖所示:

運行之后,會出現ildasm的窗口,如下圖所示:

下一步,打開剛才編譯好的exe程序,如下圖所示:

展開結點,并找到“MyDelegate”類型,將其展開,如下圖所示:

在上圖中,我們可以看到,對“MyDelegate”,存在如下“說明”:

extends [mscorlib]System.MulticastDelegate

與此同時,還存在著四個方法,即:

Ø?.ctor:構造方法

Ø?BeginInvoke

Ø?EndInvoke

Ø?Invoke

l????????MulticastDelegate類

MultiDelegate類是一個特殊類(Special Class),和System.Delegate類一樣,該類只能夠被編譯器以及內置的工具類所繼承,我們自定義的類是不能夠顯式的繼承自該類的。

MultiDelegate類當中可以包括一個委托的鏈表,這個表中,可以包括一個或多個元素(每個元素都是一個委托),我們可以將這個表稱為調用鏈。當我們調用一個MultiDelegate的時候,位于該MultiDelegate調用鏈中的委托就會被串行調用。這樣我們就可以只調用一個方法,而多個相同簽名的方法就會同時被串行調用。關于多播委托的說明,我們會在后面的內容中進行講解。

l????????Invoke方法

為了解釋Invoke方法,我們先來回顧一下,當一個委托指向了一個方法時是如何調用的,代碼如下所示:

int c = this.md(a,b);

我們在調用委托,并執行該委托所指向的方法時,本質上就是調用了其Invoke方法。實際上,我們可以直接調用其Invoke方法,代碼如下所示:

int c = this.md.Invoke(a,b);

另外,與Invoke方法對應的BeginInvoke,是對Invoke方法的一個異步調用,而EndInvoke是異步調用完成后的處理方法,關于異步調用的說明,我們將在多線程的章節中進行說明。

6.1.3使用多播委托(MulticastDelegate

前面剛剛提及到MulticastDelegate,下面我們來看一下它的應用。

有的時候,我們想要調用一個委托,但同時可以執行多個方法(自定義事件中最為常見),比如,一個工作文檔生成之后,系統要將生成文檔日志,而且還要被保存到數據庫中,對于以上個操作,如果只想調用一個委托,就可以順序完成,那么使用多播委托,就可以實現。

多播委托(MulticastDelegate)提供了一種類似于流水線式的鉤子機制只要加載到這條流水線上的委托,都會被順序執行。因為所有的委托都繼承自MulticastDelegate,因此所的委托都具備多播特性。

下面能過一個控制臺程序來說明多播委托(MulticastDelegate)的使用方式。

l????????案例操作050602:使用多播委托

首先,建立一個控制臺程序。在其中添加兩個具備相同簽名的方法

Ø?void CreateLogFile(string originalPath):用于創建日志文件

Ø?void WriteToDb(string originalPath):用于將文件寫入數據庫

代碼如下:

方法:void CreateLogFile(string originalPath)

///

///用于生成日志文檔

///

///文件的原始路徑

static void CreateLogFile(string originalPath)

{

??? if (!Directory .Exists ("log"))

??? {

???????? Directory.CreateDirectory("log");

???? }

???? StreamWriter sw = new StreamWriter("log/log.txt" ,true);

???? sw.WriteLine("新文件已經創建,創建時間:{0},文件路徑:{1}",DateTime .Now .ToLongTimeString (),originalPath );

???? sw.Close();

???? Console.WriteLine("已經寫入日志!");

}

方法:void WriteToDb(string originalPath)

///

///用于將文件寫入數據庫

///

///文件的原始路徑

static void WriteToDb(string originalPath)

{

???? FileStream fs = new FileStream(originalPath ,FileMode.Open );

???? var buffer=new byte[fs.Length ];

???? fs.Read(buffer ,0,buffer.Length );

???? fs.Close();

?

???? SqlConnection con = new SqlConnection("server=.;database=test;uid=sa;pwd=sa");

???? SqlCommand cmd = con.CreateCommand();

???? cmd.CommandText = "insert into tb_files values(@ID,@FileName,@CreationTime,@FileBytes)";

???? cmd.Parameters.Add("@ID",SqlDbType.UniqueIdentifier).Value=Guid.NewGuid ();

???? cmd.Parameters.Add("@CreationTime",SqlDbType.DateTime).Value =DateTime.Now ;

???? cmd.Parameters.Add("@FileName",SqlDbType.NText).Value=Path.GetFileName (originalPath);???????????

???? cmd.Parameters.Add("@FileBytes",SqlDbType.Image ).Value=buffer? ;

?

???? con.Open();

???? cmd.ExecuteNonQuery();

???? con.Close();

???? Console.WriteLine("已經寫入數據庫");

}

上面兩個方法,具備相同簽名,如果想同時串行調用這兩個方法,還要定義一個委托類型,代碼如下:

///

///生成一個委托,用于實現多播操作

///

///文件的原始路徑

delegate void MyMulticastDelegate(string path);

主函數代碼如下所示:

static void Main(string[] args)

{

??? //創建原始文件

???StreamWriter sw = new StreamWriter("new file.txt",false );

??? sw.WriteLine("this is a new file");

??? sw.Close();

?

??? //創建委托,并指向CreateLogFile方法

???MyMulticastDelegatelogDelegate=new MyMulticastDelegate (CreateLogFile);

??? //創建委托,并指向WriteToDb方法

???MyMulticastDelegate dbDelagate = new MyMulticastDelegate(WriteToDb );

?

?

??? MyMulticastDelegate multicastDelegate = logDelegate;

??? //在多播委托的調用鏈中添加新的委托元素

???multicastDelegate = multicastDelegate + dbDelagate;

?

??? //調用多播委托,并且序列執行兩個委托所指向的方法

???multicastDelegate("new file.txt");

?

}

在主函數中,首先創建一個原始文件,然后建立兩個委托分別指向CreateLogFile方法以及WriteToDb方法,如下代碼段所示:

???MyMulticastDelegatelogDelegate=new MyMulticastDelegate(CreateLogFile);

??? MyMulticastDelegate dbDelagate = new MyMulticastDelegate(WriteToDb );

下一步,將這兩個方法合并到一個多播委托中,代碼如下所示:

MyMulticastDelegate multicastDelegate = logDelegate;

??? multicastDelegate = multicastDelegate + dbDelagate;

最后,利用多播委托,同時串行執行兩個操作,代碼段如下所示:

multicastDelegate("new file.txt");

從上面的代碼中,我們可以發現,對于兩個委托來講,“+”加操作是有意義的。如下面代碼所示:

MyMulticastDelegate multicastDelegate = logDelegate;

??? multicastDelegate = multicastDelegate + dbDelagate;

這一點可以說明,如果想要將兩個委托,放入到一個多播委托的調用鏈中,可以使用“+操作符,換句話說,對于委托的“+”操作,就是在調用鏈中增加一個新的結點,并將一個新委托放置到該結點中。另外,和int類型的自加操作類似,委托的自加操作也進行簡寫,這種寫法在注冊事件的時候較為常用,代碼如下:

MyMulticastDelegate multicastDelegate = logDelegate;

multicastDelegate+= dbDelagate;

?

該案例的完整代碼如下:

///

///用于生成日志文檔

///

///文件的原始路徑

static void CreateLogFile(string originalPath)

{

??? if (!Directory .Exists ("log"))

??? {

???????? Directory.CreateDirectory("log");

???? }

???? StreamWriter sw = new StreamWriter("log/log.txt" ,true);

???? sw.WriteLine("新文件已經創建,創建時間:{0},文件路徑:{1}",DateTime .Now .ToLongTimeString (),originalPath );

???? sw.Close();

???? Console.WriteLine("已經寫入日志!");

}

///

///用于將文件寫入數據庫

///

///文件的原始路徑

static void WriteToDb(string originalPath)

{

???? FileStream fs = new FileStream(originalPath ,FileMode.Open );

???? var buffer=new byte[fs.Length ];

???? fs.Read(buffer ,0,buffer.Length );

???? fs.Close();

?

???? SqlConnection con = new SqlConnection("server=.;database=test;uid=sa;pwd=sa");

???? SqlCommand cmd = con.CreateCommand();

???? cmd.CommandText = "insert into tb_files values(@ID,@FileName,@CreationTime,@FileBytes)";

???? cmd.Parameters.Add("@ID",SqlDbType.UniqueIdentifier).Value=Guid.NewGuid ();

???? cmd.Parameters.Add("@CreationTime",SqlDbType.DateTime).Value =DateTime.Now ;

???? cmd.Parameters.Add("@FileName",SqlDbType.NText).Value=Path.GetFileName (originalPath);???????????

???? cmd.Parameters.Add("@FileBytes",SqlDbType.Image ).Value=buffer? ;

?

???? con.Open();

???? cmd.ExecuteNonQuery();

???? con.Close();

???? Console.WriteLine("已經寫入數據庫");

}

///

///生成一個委托,用于實現多播操作

///

///文件的原始路徑

delegate void MyMulticastDelegate(string path);

?

static void Main(string[] args)

{

??? //創建原始文件

???StreamWriter sw = new StreamWriter("new file.txt",false );

??? sw.WriteLine("this is a new file");

??? sw.Close();

?

??? //創建委托,并指向CreateLogFile方法

???MyMulticastDelegatelogDelegate=new MyMulticastDelegate (CreateLogFile);

??? //創建委托,并指向WriteToDb方法

???MyMulticastDelegate dbDelagate = new MyMulticastDelegate(WriteToDb );

?

?

??? MyMulticastDelegate multicastDelegate = logDelegate;

??? //在多播委托的調用鏈中添加新的委托元素

???multicastDelegate = multicastDelegate + dbDelagate;

?

??? //調用多播委托,并且序列執行兩個委托所指向的方法

???multicastDelegate("new file.txt");

?

}

該案例的運行效果如下:

首先,系統中并不存在日志文件,如下圖所示:

用于儲存文件的數據庫結構如下:

數據表中的原始數據為空,如下圖所示:

執行完程序之后,窗口的效果如下圖所示:

日志文件已經生成,內容如下圖所示:

數據庫的效果如下圖所示:

?

6.1.4匿名方法

在前面的代碼中,用戶可以發現,在使用委托時,無論該代碼難易,都需要將功能性代碼放置在一個方法中,再利用委托指向該方法。在C#2.0以及C#3.0中這種情況得到了改善,在C#2.0中,我們可以利用匿名方法(Anonymous Method)來簡化委托的使用,在C#3.0中,我們可以Lambda表達式使其得到進一步簡化,關于Lambda表達式的相關內容,請參見C#3.0程序設計。

所謂匿名方法(Anonymous Method),是指在使用委托時,可以不再事先定義一個方法,然后再讓委托指向方法,匿名委托允許開發人員,使用內聯方式,直接讓一委托指向一個功能代碼段。下面代碼對比了傳統方法中委托的會用,以及利用匿名方法的簡化操作:

l????????傳統方法使用委托:先定義一個方法,再定義委托,并指向方法

public void Run()

{

??? StreamWriter sw = new StreamWriter("e:\ex\log.txt",true );

??? for (int i = 0; i < 10000000; i++)

??? {

??????? sw.WriteLine(i.ToString ());

??? }

??? sw.Close();

}

delegate void MyDelegate();

protected void Button2_Click(object sender, EventArgs e)

{

??? MyDelegate md = new MyDelegate(this.Run );

??? md();

}

l????????利用匿名方法簡化委托的使用

delegate void MyDelegate();

protected void Button2_Click(object sender, EventArgs e)

{

?? MyDelegate md = new MyDelegate(

????? delegate()

????? {

???????? StreamWriter sw = new StreamWriter("e:\ex\log.txt", true);

???????? for (int i = 0; i < 10000000; i++)

???????? {

????????????? sw.WriteLine(i.ToString());

????????}

???????? sw.Close();

?????? }

?????? );

?? md();

}

從上面代碼的對比中,不難發現,使用匿名方法,省去了定義方法的步驟。實際上,在多線程編程的時候,使用匿名方法可以使得代碼變的簡化,并提高了可讀性。下面代碼是在不使用匿名方法的情況下編寫多線程代碼:

public void Run()

{

??? for (int i = 0; i < 1000000; i++)

??? {

??????? this.textBox1.Text = i.ToString();

??? }

??? thread.Abort();

}

Thread thread = null;

private void button1_Click(object sender, EventArgs e)

{

??? CheckForIllegalCrossThreadCalls = false;

??? this.thread = new Thread(new ThreadStart (this.Run ));

??? this.thread.Start();

}

利用匿名方法,可以將上面的代碼改寫為:

private void button1_Click(object sender, EventArgs e)

{

?

???? CheckForIllegalCrossThreadCalls = false;

???? Thread thread = null;

???? thread = new Thread(

????????? delegate()

????????? {

????????????? for (int i = 0; i < 1000000; i++)

????????????? {

?????????????????? this.textBox1.Text = i.ToString();

????????????? }

????????????? thread.Abort();

?????????? }

???????? );

???? thread.Start();

}

使用內聯方式可以讓代碼更好理解!

6.2自定義事件

自定義事件,是委托的一個典型應用!開發人員在編寫WinForm或者ASP.NET應用程序時,都會使用ButtonClick事件。那么,這種事件觸機制是如何實現的呢?我們能不能編寫自己定義的事件;另外,我們需要在什么時候編寫自己定義的事件呢?

6.2.1為什么要使用自定義事件

很多開發人員都會向筆者提出這樣的問題“我們為什么要自己編寫事件?控件里面已經集成了很多的事件,這還不夠我們用嗎?”。

實現上,如果不清楚掌握如果編寫自定義事件,想要開發出真正能用的應用程序是很困難的。其主要原因有以下兩點:

1.自定義控件

通常情況下,開發人員為了減少重復界面功能代碼的編寫量,往往會開發出一些用戶控件或者是自定義控件。這時,我們就會產生問題,微軟為我們提供的控件中包括了大量的事件,那么我們自己編寫的控件中,是不是也會存在很多的事件呢?

2.自己編寫的組件及類庫

事件并不是UI層的控件類所專有的,很多底層的類也都包括了事件,比如SqlConnection類,該類的類視圖如下所示:

在這個類中就包括了一個InfoMessage事件,該事件作用是“ SQL Server 返回一個警告或信息性消息時發生”。也就是說,在我們自己編寫一個類的時候,往往會發生一種特殊的數據傳遞情況,即:數據的傳遞的方向是由下向上的。為了解釋這種“由下向上”的傳遞方式,我們先來看一個應用程序的分層結構圖:

上圖是一個比較常規的Socket通信軟件的三層構架圖,客戶端及服務器的界面是兩個“EXE”程序,但是為了系統的邏輯更好管理,我們通常是將所的通信邏輯封裝到業務邏輯層的兩個“DLL”文件中。圖中箭頭方向說明整個系統功能的實現,是界面的“EXE”調用底層的“DLL”實現的。

然而,所有通信的功能都是在DLL中所定義的類里實現的,那么,當客戶端的DLL向服務器的DLL發送了一個消息,并被服務器的“DLL”所截獲之后,服務器界面的“EXE”又是怎么得知的呢?我們平時在使用QQMSN的時候有沒有想過這樣的問題呢?

這個時候,又出現了我們剛才提到的那個問題“由下向上”,即,由下層“DLL”中的類,通知上層“EXE”中的界面。我們總不能再使用DLL調用一次EXE吧!

注意:在一般情況下.NET平臺的DLL是可以引用EXE的,但是如上圖所示,EXE已經對DLL進行了引用,此時IDE就不再允許DLLEXE進行引用,這是為了防止發生循環引用產生死鎖。即使IDE允許我們再利用DLL引用EXE,引用之后所創建的實例和當前運行的界面的實例也是位于不同內存的,所以任何操作都不會生效。

此時,利用委托實現的事件機制就可以為我們解決問題!

6.2.2控件中的事件

為了理解事件機制,首先從控件中的事件談起。我們以ButtonClick事件為例進行說明。

當開發人員雙擊了Button之后,IDE會將設計器轉向代碼視圖,并為我們生成一個用于事件回調的方法,如下圖所示:

注意:這里的button1_Click并不是事件,它僅僅是事件發生時所調用的方法!

我們的問題是,為什么在Button1Click事件發生之后,button1_Click方法就會被調用呢?實際上,在我們雙擊Button1的時候,IDE自動的添加了一段代碼,該段代碼位于“Form1.Designer.cs”中(.NET1.1中并不包括Form1.Designer.cs),“Form1.Designer.cs”的位置如下圖所示:

打開Form1.Designer.cs,并展開“InitializeComponent()”方法,找到第42行,如下圖所示:

我們可以看到如下代碼:

this.button1.Click += new System.EventHandler(this.button1_Click);

實際上這段代碼,也就是所謂的事件注冊代碼。該代碼的意思是:如果this.button1Click事件發生之后,就轉向this. button1_Click方法進行處理。

為了更好的理解事件的注冊過程,我們先第42行代碼進行修改,如下圖所示:

這里,我們將原來的

this.button1.Click += new System.EventHandler(this.button1_Click);

修改為

this.button1.Click = new System.EventHandler(this.button1_Click);

在這個程序里,這的修改是為了更好理解,當然這種寫法是語法錯誤的。

下面我們對其進行分析:

首先,觀察“=”右面的表達式。

new System.EventHandler(this.button1_Click);

通過6.1.1一節中的說明,大家可以發現,這段代碼實際上是建立了一個委托類型的實例,并讓該委托指向了this.button1_Click方法。也就是說,在程序運行的“某一時刻”,系統會通過這個委托實例間接的調用this.button1_Click方法。

然后,我們再來觀察“=”左面的表達示。在C風格的語言中“=”是賦值表達式,也就是說,“=”兩側表達式的數據類型應該是一樣的。因此,既然“=”右側的表達式是一個委托類型(System.EventHandler)的實例,那么this.button1.Click也應該是一個委托類型(System.EventHandler)。

通過上面的說明,我們得到一個信息,前面這段事件注冊代碼,是讓this.button1.ClickSystem.EventHandler(this.button1_Click)指向了同一段內存空間,簡單來,就是讓this.button1.Click指向了this.button1_Click方法,調用了this.button1.Click,就相當于調用了this.button1_Click方法。因此,我們說,當this.button1Click事件發生之后,方法this.button1_Click就會被調用。

在程序運行的時候,系統會自己檢測this.button1是否被點擊了,如果被點擊了,就在button1的內部調用button1.Click,這時,Windows窗口中的button1_Click方法就會被執行。

當然,事件注冊代碼完全可以手寫。因為,除了控件中事件注冊代碼是自動生成以外,其他類中的事件注冊都是手寫的。手工注冊事件的方法如下:

首先,可以在事件發生之前的任何代碼中添加事件(通常是在窗口的構造方法中),下面我們來手工注冊button1MouseMove事件,如下圖所示:

當我們寫完“=”時,會出現一個提示“Press TAB to insert”,這時,我們只需要按2下“TAB”鍵,事件的注冊以及用于回調的方法,就會自己添加到代碼窗口里,如下圖所示:

自動生成的代碼是將this.button1MouseMove事件指向了button1_MouseMove方法。這樣手寫的代碼和IDE自動生成的代碼是完全一樣的。

當然,作為控件的事件,我們完全可以自動生成,如果想自動生成button1的其他事件,只需要查看button1的屬性窗口,并點擊“”按鈕,就會出現該控件的事件列表,如下圖所示:

然后雙擊你想要的事件,代碼就會自動生成了。

在前的面代碼中為了更好理解事件注冊,我們曾將

this.button1.Click += new System.EventHandler(this.button1_Click);

修改為

this.button1.Click = new System.EventHandler(this.button1_Click);

我們會發現,無論是自己寫的事件注冊代碼,還是自動生成的代碼,都是使用“+=”來實現的,實際上,作為事件注冊的代碼,我們僅僅能夠使用“+=”來實現注冊,簡單的使用“=”是語法錯誤的!!!

+=”操作符在C風格語言中是常用的操作符,比如

int i=0;

i+=1;

等同于

int i=0;

i=i+1;

因此,

this.button1.Click += new System.EventHandler(this.button1_Click);

在原則上等同于

this.button1.Click= this.button1.Click+

new System.EventHandler(this.button1_Click);

用自然語言來描述上面的代碼就是“一個委托=這個委托本身+另外一個委托”。那么委托相加意味著什么呢?

6.1.3一節中,我們討論過MultiDelegate(多播委托),而事件本身也是委托,并且所有委托都是System.MultiDelegate類的派生類,在6.1.3中,我們曾經演示過,多個委托類型實例相加,就是將這些委托實例存放在一個多播委托的調用鏈中,當調用多播委托時,該多播委托的調用鏈中的所有委托都會順序的被調用。

利用多播委托的原理,我們可以將多個方法注冊給一個事件,如下所示:

this.button1.Click+=new System.EventHandler(this.button1_Click);

this.button1.Click +=new System.EventHandler(this.button1_Click1);

this.button1.Click +=new System.EventHandler(this.button1_Click2);

上面的代碼,就將三個方法注冊到了button1Click事件中,button1Click事件觸發之后,方法button1_Clickbutton1_Click1button1_Click2將會被順序調用。這樣作的好處是,我們可以將多個功能以及邏輯完全獨立的操作放在不同的方法中,當事件發生之后,這方法將會順序的被調用,以實現我的需要的級聯操作。

6.2.3控件中事件的回調方法

說完了事件的注冊,下面我們來談一下事件的回調方法。首先,我們還要再一次回顧事件注冊的代碼:

this.button1.Click+=new System.EventHandler(this.button1_Click);

上面代碼中,使用“new System.EventHandler(this.button1_Click)”將一個System.EventHandler委托類型的實例指向了this.button1_Click方法。通過6.1.1一節中所談到的內容,我們知道,如果想讓一個委托指向一個方法,那么該委托以及所被指向的方法一定要具備相同的簽名(Signature,具備相同的參數列表,相同的返回值)。因此,System.EventHandler類型和this.button1_Click方法具備相同的簽名,下面,我們來看一下System.EventHandler委托的簽名是什么樣的:

public delegate void EventHandler(

?????????????Object sender,

?????????????EventArgs e

)

System.EventHandler的簽名是:返回值為void;有兩個參數,Object sender, EventArgs e。因此button1_Click方法也具備相同形式,代碼如下:

private void button1_Click(object sender, EventArgs e)

{

?

}

實際上,我們所能夠看到的事件回調方法的簽名基本上都著不多,只不過第二個參數略有區別,下面,我們對該方法的參數進行說明。

&Oslash;????????Object sender

從該參數的命名上,可以看出其作用,sender(發送者)的意思是:誰觸發的這個事件,那么sender就是誰,由于所有的類型在理論上講都可以包括事件,因此sender的類型被定義成Object類型,當多個事件同時指向一個事件回調方法的時候,通過該參數可以區分出是哪一個類觸發的事件,以便做出不同的處理,此時,需要對參數sender作出類型轉化。

l????????案例操作020603:多個事件指向同一個回調方法

首先,添加三個Button,一個TextBox

界面如下:

然后,在主窗口中添加一個方法ButtonClick,這三個按鈕的Click事件將調用該方法。

代碼如下:

protected void ButtonClick(object sender, EventArgs e)

{

???? Button bt = sender as Button;

???? this.textBox1.Text ="我是:"+ bt.Text;

}

上面代碼中,為了知道點擊的是哪個按鈕,我們將sender轉化成了Button類型。

下面來指定這三個按鈕的Click事件回調方法

首先,切換到button1的屬性窗口(F4),點擊“”按鈕,找到“Click”事件,并設置所調用的方法名為ButtonClick,如下圖所示。

然后,以相同的方法設置button2,button3Click事件,并它們都指向ButtonClick方法。

最后,運行程序,下面是運行情況:

點擊button1:

點擊button2:

點擊button3:

?

&Oslash;????????EventArgs e

EventArgs類型是事件參數,當事件發生時,可以通過該參數來傳遞一些數據。當然EventArgs類本身是傳遞不了什么數據的,該類的類視圖如下:

從類視圖中不難發現,該類中的成員很少,通常情況下,如果想傳遞數據,那么事件參數類一般會是一個EventArgs類的派生類。比如TextBox類的KeyDown事件中事件參數就是一個KeyEventArgs類型的參數,事件回調方法的原型如下:

private void textBox1_KeyDown(object sender, KeyEventArgs e)

{

?

}

KeyEventArgs類的類視圖如下所示:

該類中有三個屬性:“Alt”,“Control”,“Shift”分另用來表示按下鍵盤某一個鍵的同時,有沒有按下這三個功能鍵。

另外“KeyCode”屬性可以用來表示當前用戶所按的鍵位名。

在下一節中,我們會說明如何編寫自定義事件參數。

l????????案例操作020604:利用TextBox的KeyDown事件來模擬QQ聊天窗口

新建一個Windows窗口,包括以下控件

一個RichTextBox控件rtbMessage:用來顯示聊天信息

一個TextBox控件(tbxInput):用來輸入聊天信息

一個Button控件( btSubmit):用來提交

界面如下所示:

功能如下:

點擊button可以讓消息傳遞到上面的RichTextBox中。當然,如果按“Ctrl+Enter”也可以使文字傳遞到RichTextBox中。

首先,我們在Windows窗口中添加一個方法,代碼如下:

public void Display()

{

???? this.rtbMessage.AppendText(this.tbxInput .Text +"n");

???? this.tbxInput.Text = "";

}

該方法的功能就是將文本框中的文字添加到RichTextBox中。

下一步,編寫ButtonClick事件,代碼如下:

private void btSubmit_Click(object sender, EventArgs e)

{

???? this.Display();

}

下一步編寫TextBoxKeyDown事件,代碼如下:

private void tbxInput_KeyDown(object sender, KeyEventArgs e)

{

???? if (e.Control ==true&&e.KeyCode .ToString ()=="Return")

???? {

?????????? this.Display();

????? }

???????????

}

該方法在執行前先檢測用戶是否同時按下的Control和回車鍵,然后再進行顯示操作。

程序運行的效果如下:

按下Control+回車之后,文字上屏,效果如下:

?


轉載于:https://my.oschina.net/liangzhenghui/blog/186408

總結

以上是生活随笔為你收集整理的C#委托及事件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

热久久99这里有精品 | 日韩超碰| 久久精品视频播放 | 亚洲婷婷丁香 | 欧美精品亚洲精品日韩精品 | 国产成人精品国内自产拍免费看 | 欧美污网站 | 97色资源| 亚洲一区精品人人爽人人躁 | 麻豆视屏 | 麻豆视频免费播放 | 99国产精品免费网站 | 成人毛片在线观看 | 亚洲精品综合一二三区在线观看 | 狠狠色丁香久久综合网 | 亚洲精品在线观看视频 | 黄色小网站在线 | 日韩大片在线免费观看 | 天天爱天天射 | 久久激情影院 | 国产精品久久精品国产 | 精品福利国产 | 99综合久久 | 91在线免费视频观看 | 91精彩视频在线观看 | 911免费视频 | 国产精品久久久久久久妇 | 99久热在线精品视频观看 | a电影免费看 | 97在线精品国自产拍中文 | 区一区二在线 | 在线观看岛国av | 国产精品毛片网 | 久久艹精品 | 黄色软件视频大全免费下载 | 在线天堂中文在线资源网 | 狠狠干婷婷 | 国产精品 日韩精品 | 免费的黄色的网站 | 日日操网站 | 少妇精品久久久一区二区免费 | 99精品视频精品精品视频 | 91亚瑟视频 | 亚洲精品tv | 国产aa免费视频 | 中文av免费| 开心激情五月婷婷 | 最近最新最好看中文视频 | 国产视频久久久 | 国产成人精品一区二区三区福利 | 欧美性网站 | 在线观看视频免费播放 | 亚洲午夜久久久久久久久久久 | 日韩一二区在线观看 | 日日操夜 | 又黄又爽又刺激的视频 | 97av在线视频| 成人免费看片网址 | 国产最新视频在线 | 久久久久久毛片 | 夜夜爱av | 欧洲亚洲女同hd | 婷婷综合在线 | 亚洲精品高清在线 | 婷婷丁香在线 | 久久观看免费视频 | 精品国产一区二区三区在线 | 久久精品99精品国产香蕉 | 日本中文字幕免费观看 | 日韩精品在线看 | 337p日本大胆噜噜噜噜 | 亚洲国产成人精品久久 | 国精产品999国精产品视频 | 日韩高清免费观看 | 久久综合久久综合九色 | 日韩av电影手机在线观看 | 欧美精品乱码久久久久久按摩 | 黄色免费网站 | 国产精品久久二区 | 手机av网站| 精品久久1 | 国产精品久久三 | 热久久国产精品 | 国产精品美女久久久久aⅴ 干干夜夜 | 91大神精品视频在线观看 | 国内精品中文字幕 | 五月婷婷丁香在线观看 | 夜夜夜夜操 | 高清免费在线视频 | 国产精品一区电影 | 国产美女视频一区 | 在线观看网站黄 | 午夜少妇| 国产精品久久久影视 | av网站免费在线 | 尤物97国产精品久久精品国产 | 久久免费高清视频 | 久久久片| 美女网站在线观看 | 久久国产精品成人免费浪潮 | 91久久爱热色涩涩 | 久久精品草 | 国产精品久久久毛片 | 欧美精品二区 | 国产v在线 | 韩国av免费 | 久久爱导航 | 日韩综合一区二区 | 欧美日韩在线视频观看 | 中文字幕大全 | av福利网址导航大全 | 亚洲综合小说电影qvod | 亚洲美女在线国产 | 久久综合九色综合久99 | 亚洲热视频 | 国产一区在线免费观看 | 色瓜| 国产成人精品av | 夜夜夜夜夜夜操 | 亚洲欧美va | 国产精品久久9 | 亚洲人成网站精品片在线观看 | 五月婷婷视频在线观看 | 天天插狠狠干 | 国产成人精品av在线 | 久久久综合香蕉尹人综合网 | 日韩a在线播放 | 人成免费网站 | 精品成人久久 | 成人精品福利 | 久久人人插| 国产精品视频不卡 | 欧美综合国产 | 97人人澡人人添人人爽超碰 | 五月婷婷视频在线 | 黄色a一级视频 | 日韩视频中文字幕在线观看 | 欧美一级视频在线观看 | 日韩免费一区二区三区 | 日日夜夜艹 | 欧美午夜一区二区福利视频 | 在线电影日韩 | 免费av片在线 | 亚洲在线网址 | 91久久久久久久 | 香蕉视频国产在线 | 日韩福利在线观看 | 天天操天天草 | 久久精品超碰 | 五月天婷婷在线观看视频 | 精品视频资源站 | 97成人在线观看视频 | 国内揄拍国内精品 | 亚洲精品综合欧美二区变态 | 国产在线国偷精品产拍免费yy | 日韩欧美在线不卡 | 极品国产91在线网站 | 国产精品高 | 中文字幕资源网 国产 | 三级黄色片在线观看 | 久久歪歪| 久久网站免费 | 91成人免费在线视频 | 精品视频国产 | 国产日韩精品在线观看 | 婷婷综合五月天 | 黄色国产高清 | 日韩视频免费看 | 国内精品久久久久久久影视麻豆 | 欧洲一区二区三区精品 | 国产精品a久久久久 | 亚洲黄色区 | 乱子伦av| 中文字幕观看在线 | 免费看片亚洲 | 欧洲精品二区 | 色视频网站在线观看一=区 a视频免费在线观看 | 99色视频 | 欧美日bb| 91最新地址永久入口 | 波多野结衣在线观看一区二区三区 | 最近乱久中文字幕 | 成人av资源站| 亚洲精品在线观看中文字幕 | 欧美性色黄大片在线观看 | 国产午夜三级一区二区三 | 最近日本mv字幕免费观看 | 深爱激情丁香 | 福利一区在线 | 18做爰免费视频网站 | 国产精品美女免费视频 | 成人午夜电影在线 | 激情偷乱人伦小说视频在线观看 | 狠狠色丁香久久婷婷综合五月 | 天天色天天射天天操 | 久久久天堂 | 色综合久久88 | 视频国产一区二区三区 | 国产精品一区二区在线 | 激情图片久久 | 亚洲视频高清 | 久久er99热精品一区二区 | 一级黄色a视频 | 日本精品在线 | 国产色在线,com | 久草在线 | 日韩在线观看一区二区 | 午夜精品久久久久久久99 | 婷婷综合久久 | 免费视频一二三区 | 狠狠综合| 免费下载高清毛片 | 少妇自拍av | 国产黄大片在线观看 | 日韩黄色网络 | 五月天最新网址 | 在线成人中文字幕 | 中文字幕在线视频一区二区三区 | 最近日韩免费视频 | 免费久久精品视频 | 欧美日韩中文字幕综合视频 | 久草干| 日韩av不卡在线播放 | 深夜国产在线 | a天堂最新版中文在线地址 久久99久久精品国产 | 久久久精品国产免费观看一区二区 | 天天草视频 | 一区二区三区在线不卡 | 91高清视频免费 | 久久久久久久久久久国产精品 | 中文在线免费观看 | 久久99精品久久久久久清纯直播 | av久久久| 亚洲精品一区二区三区四区高清 | 色综合婷婷 | 97福利 | 欧美一级片免费在线观看 | 一本到在线 | 亚洲婷婷在线视频 | 久草电影在线观看 | 黄色av电影在线观看 | 日韩国产精品久久久久久亚洲 | www久久com| 91麻豆国产福利在线观看 | 91热这里只有精品 | 手机av网站 | 在线之家免费在线观看电影 | 国产麻豆果冻传媒在线观看 | 亚洲伊人av | 欧美综合在线视频 | 中文字幕国语官网在线视频 | 免费在线观看av的网站 | 96久久欧美麻豆网站 | 午夜av一区 | 91天天操| 成人禁用看黄a在线 | 日韩欧美69 | 手机看片 | 亚洲精品在线观看的 | 成年人免费看片 | 黄色网www| 国产手机在线视频 | 一区 二区 精品 | 午夜丁香网 | 亚洲日本va中文字幕 | 亚洲国产播放 | 午夜久久久久久久久 | 亚洲国产美女精品久久久久∴ | 色偷偷88888欧美精品久久 | 国产又黄又爽无遮挡 | 国产成人区 | 久久精品国产一区二区三区 | 黄色亚洲大片免费在线观看 | 国产日韩中文字幕 | 天天草天天草 | 亚洲乱码久久 | 日韩中文字幕亚洲一区二区va在线 | 久久久久亚洲精品中文字幕 | 夜夜骑首页 | 五月天久久婷 | 免费看的国产视频网站 | 成人h视频在线播放 | 91九色成人蝌蚪首页 | 91视频在线播放视频 | www.天堂av | 国产精品美女久久久久久久 | 久久成年人网站 | 女人18精品一区二区三区 | 国产精品v a免费视频 | 13日本xxxxxⅹxxx20 | 国产精品色在线 | 欧美性生活大片 | 国产成人一区二区三区影院在线 | 中文字幕电影网 | 久久久穴 | 激情偷乱人伦小说视频在线观看 | 香蕉视频在线观看免费 | 欧美一级片免费观看 | 热久久国产 | 日韩午夜电影院 | 久久综合久久综合九色 | 久久天堂网站 | 色片网站在线观看 | 91尤物国产尤物福利在线播放 | 亚洲国产精品资源 | 欧美成人在线免费观看 | www日 | 午夜精品久久久久久99热明星 | 超级碰碰免费视频 | 在线观看免费日韩 | 精品美女国产在线 | www.久久免费 | 制服丝袜在线91 | 久久综合九色综合久99 | 天天干天天操天天操 | 午夜 在线 | 成人精品亚洲 | 伊人婷婷 | 亚洲成人网av | 国产999久久久 | 中文字幕在线视频精品 | 黄色免费网站大全 | 成年人在线看视频 | 日韩av一区在线观看 | 亚洲精品综合欧美二区变态 | 亚洲第一香蕉视频 | 色综合天天干 | 在线视频 国产 日韩 | 中文字幕视频三区 | 久久久久成人免费 | 五月天丁香视频 | 久草久草视频 | 亚洲一区二区高潮无套美女 | 高清国产午夜精品久久久久久 | 久久久久欧美精品999 | 黄色资源在线观看 | 国产高清av| 97在线观视频免费观看 | 又黄又爽又湿又无遮挡的在线视频 | 日韩中文在线观看 | 日日躁夜夜躁xxxxaaaa | 美女精品国产 | 国产精品一区二区在线观看 | 成人a在线观看高清电影 | 国产 亚洲 欧美 在线 | 国产欧美精品xxxx另类 | 高潮久久久久久 | 国产免费久久精品 | 日韩羞羞 | 日本资源中文字幕在线 | 不卡av免费在线观看 | 国产成人三级三级三级97 | 国产精品美女久久久久aⅴ 干干夜夜 | 国产不卡视频在线 | 91免费观看| 欧美aa在线 | 免费观看黄| 国产自制av| 国产在线p | 国产精品久久久久久欧美 | 亚洲欧洲精品一区二区 | av免费观看在线 | 久久综合色综合88 | 香蕉97视频观看在线观看 | 欧美一级高清片 | 93久久精品日日躁夜夜躁欧美 | 久久人人爽人人爽人人片av软件 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 黄色免费网站下载 | 久草在线网址 | 毛片在线播放网址 | 欧美一区在线看 | 日本久久不卡视频 | 久久精品国产亚洲 | 国产色黄网站 | 在线黄色国产电影 | 人人干干人人 | 国产精品久久婷婷六月丁香 | 国产中文欧美日韩在线 | 在线观看黄色免费视频 | 国产这里只有精品 | 欧美国产精品一区二区 | 亚洲精品中文字幕在线观看 | 91私密视频| av电影一区 | 九九免费在线看完整版 | 久草在线视频精品 | 久久影视中文字幕 | 人人超碰在线 | 鲁一鲁影院| 日本高清中文字幕有码在线 | 丁香亚洲 | 成人一区二区三区在线观看 | 三级毛片视频 | 国产成人精品一区二区三区福利 | 欧美最猛性xxxxx免费 | 99精品视频免费 | 国产亚洲精品无 | 日韩在线视 | 最近2019中文免费高清视频观看www99 | 亚一亚二国产专区 | 国产精品不卡 | 欧美国产一区在线 | 五月天久久婷婷 | 麻豆国产精品一区二区三区 | 国产日韩欧美综合在线 | 最近高清中文在线字幕在线观看 | 久久久久久久久久电影 | 国产精品成人一区 | av免费成人| 日韩在线第一区 | 婷婷 综合 色 | 久久久午夜精品理论片中文字幕 | 久久久精品 一区二区三区 国产99视频在线观看 | 天天天天天天天操 | 久久成人午夜 | 超碰在线97免费 | 国产日韩一区在线 | 国产日韩欧美在线免费观看 | 欧美日韩国产一区二区三区在线观看 | 91精品国自产在线观看欧美 | 久久精品4 | 国产不卡一二三区 | 欧美另类网站 | 在线99视频| 欧美淫视频| 免费观看一级成人毛片 | 伊色综合久久之综合久久 | 午夜视频色 | 国产精品久久久久影院 | 美女av在线免费 | 69视频永久免费观看 | 在线 视频 亚洲 | 欧美在线一二 | 日韩免费在线观看视频 | 国产黄色一级片 | 日韩欧美在线第一页 | 夜夜干天天操 | 欧美日韩高清在线一区 | 色多多在线观看 | 久久久网站 | 日韩一二区在线 | 日日操狠狠干 | 91丨九色丨高潮丰满 | 日韩国产在线观看 | 91av在线免费看 | 国产成人精品综合久久久久99 | 亚洲免费国产视频 | 久久久免费高清视频 | 国产精品久久伊人 | 天天干天天操天天爱 | 日韩在线视频免费看 | 97在线播放视频 | 99久久精品视频免费 | 99久久超碰中文字幕伊人 | av+在线播放在线播放 | 亚洲1区 在线| 玖玖在线资源 | 精品国产一区二区三区四区在线观看 | 日本中文字幕在线看 | 四虎永久免费在线观看 | 亚洲视频 一区 | 伊人五月| 欧美精品亚洲精品日韩精品 | 综合精品久久久 | 久久试看 | 国产精品va| 国产精品综合在线观看 | 五月婷婷丁香在线观看 | 国产护士在线 | 激情综合电影网 | 最近高清中文在线字幕在线观看 | 久久99久久精品 | 久久线视频 | 精品国产伦一区二区三区观看体验 | 成片免费观看视频 | 国内精品久久久精品电影院 | 91最新网址在线观看 | 国产免费又粗又猛又爽 | 五月婷婷中文网 | 成人av免费电影 | 在线 精品 国产 | 日日夜色| 久爱精品在线 | 在线成人免费 | 九九免费观看全部免费视频 | 91麻豆精品国产91 | 婷婷六月综合网 | 国产a精品 | 玖玖视频| 国产精品精品国产色婷婷 | 国产高清专区 | 高清精品在线 | 亚洲精品三级 | 久久精品欧美一区二区三区麻豆 | 国产视频首页 | www.久久婷婷 | 麻豆va一区二区三区久久浪 | 最近日本韩国中文字幕 | 国偷自产视频一区二区久 | 亚洲资源一区 | 天天综合网天天 | 久久久私人影院 | 久一在线 | 中国黄色一级大片 | 伊人狠狠干 | 久久综合精品一区 | 久久 一区 | 天天操网 | 五月天六月丁香 | 亚洲一区免费在线 | 欧美日韩国产区 | 国产黄网站在线观看 | 天天插一插 | 欧美日韩精品在线观看视频 | 精品亚洲视频在线 | 韩国精品在线 | 日韩精品不卡 | 国产黄色片久久久 | 国产99久久九九精品免费 | 麻豆观看 | 精品在线观看一区二区 | 中文字幕在线字幕中文 | 日韩电影久久久 | 人人精品久久 | 久久精品国产亚洲精品 | 国产九色91 | 精品乱码一区二区三四区 | 黄色三级免费观看 | 国产精品电影一区 | 九九九九九精品 | 亚洲视频1区2区 | 91av综合 | 九九久久视频 | 欧美日韩高清一区二区三区 | 久久精品老司机 | 色综合五月天 | 国产在线一区二区三区播放 | 久久有精品| 久久视屏网 | 免费在线观看一区 | 亚洲精品国产自产拍在线观看 | 亚洲综合欧美日韩狠狠色 | 999久久国产精品免费观看网站 | 中文字幕亚洲综合久久五月天色无吗'' | 深爱激情综合网 | 欧美日韩一区二区免费在线观看 | 在线精品在线 | 久久成人免费电影 | 日本久久久影视 | 91免费看黄| 天天干,天天干 | 免费在线观看午夜视频 | 精品天堂av | 欧美精品国产综合久久 | 中文视频在线看 | 欧美一区二区日韩一区二区 | 波多野结衣视频一区 | 国产不卡在线观看 | 亚洲高清视频在线播放 | av网站在线免费观看 | 欧美成人91 | av高清免费在线 | 日韩中字在线观看 | 97综合在线| 日韩精品久久久久久久电影竹菊 | 国际精品网 | 在线有码中文字幕 | 91经典在线 | 91最新在线| 在线欧美最极品的av | av黄色在线播放 | 69久久久| 特级黄色片免费看 | 四虎在线永久免费观看 | 日韩深夜在线观看 | 午夜免费视频网站 | 日韩极品视频在线观看 | 激情网五月婷婷 | 午夜国产在线 | 国产精品久久久久永久免费观看 | 国产福利在线不卡 | av在线之家电影网站 | 日本婷婷色 | 操操综合 | 91精品老司机久久一区啪 | 日韩精品第1页 | 日韩av福利在线 | 欧美午夜性 | 99精品在线看 | 黄色小说在线观看视频 | 91麻豆精品国产自产在线 | 国产精品视频免费 | 午夜18视频在线观看 | 日韩欧美xxxx | 在线看中文字幕 | 色的网站在线观看 | 精品视频专区 | 99国产免费网址 | 91精品国产综合久久久久久久 | 中文在线 | 91精品国产自产在线观看永久 | 日韩美精品视频 | 亚洲国产精品视频 | 中文字幕在线观看你懂的 | 国产高清中文字幕 | 91九色蝌蚪视频在线 | av一区在线播放 | 中文字幕亚洲不卡 | 日韩电影中文,亚洲精品乱码 | 中文字幕在线播放av | 天天射天天搞 | 青青河边草手机免费 | 99中文在线| av大全在线观看 | 一级免费片| av黄色成人 | 黄色影院在线观看 | 国产高清精品在线观看 | 国产在线视频一区二区 | 亚洲成人午夜在线 | 成人在线黄色电影 | 午夜美女福利直播 | 欧美欧美| 国产视频资源在线观看 | 国产录像在线观看 | 在线精品视频免费播放 | 久久综合色天天久久综合图片 | 久久久久黄色 | 国产91精品一区二区麻豆网站 | 免费av黄色 | 99爱视频| 亚洲视频一区二区三区在线观看 | 九九国产精品视频 | 国产亚洲综合性久久久影院 | 国产五码一区 | 日韩色一区二区三区 | 国产成人综合在线观看 | 超碰在线94 | 99热在线国产精品 | 国产精品淫 | 超级碰碰碰视频 | 国产精品精 | 蜜桃视频成人在线观看 | 99久久精品国产亚洲 | 黄色免费大全 | 久久婷婷五月综合色丁香 | 在线中文视频 | 伊在线视频 | 日韩久久久久久久久久久久 | 成人在线一区二区 | 97人人澡人人添人人爽超碰 | 婷婷深爱激情 | 欧美一级片 | 天天色天天 | 99视频精品视频高清免费 | 国内精品免费 | 一区二区精品在线 | 国产无套精品久久久久久 | 黄色成人小视频 | 在线免费黄 | 国产日韩精品视频 | 成人久久久久久久久久 | 婷婷久久五月天 | 亚洲精品午夜一区人人爽 | 手机看国产毛片 | 国产精品久久久久久婷婷天堂 | 丁香资源影视免费观看 | 99在线精品视频观看 | 精品999久久久 | 色999视频 | 狠狠色狠狠色综合日日92 | 日韩欧美一区二区在线观看 | 亚洲视频网站在线观看 | 欧美日韩精品在线 | 久久久久久久久久久影院 | 激情五月综合网 | 欧美日韩精品影院 | 视频一区二区精品 | 婷婷av网 | 欧美色就是色 | 深爱激情五月综合 | 97在线观看视频免费 | 精品久久九九 | 国产1区2 | 亚洲男女精品 | 精品91久久久久 | 国产91全国探花系列在线播放 | 美女网站免费福利视频 | 久久久久久久久久久高潮一区二区 | 亚洲黄色在线 | 91在线入口| 国产精品黄色在线观看 | 999久久久欧美日韩黑人 | 精品一区二区三区在线播放 | 亚洲欧美国产精品18p | 成 人 黄 色 免费播放 | 日韩精品欧美专区 | 91黄色视屏 | 日韩特黄av | 少妇超碰在线 | 男女免费av| 黄色成人av | 国产精品免费久久久久久久久久中文 | 日韩午夜在线观看 | 在线观看久草 | 成 人 黄 色 视频 免费观看 | www久草| 婷婷激情综合五月天 | 日韩激情综合 | 99久久99久久精品国产片 | 高清国产午夜精品久久久久久 | 午夜精品久久久久久久99水蜜桃 | 亚洲免费婷婷 | 国产精品入口66mio女同 | 国产精品日韩久久久久 | 天天综合狠狠精品 | 久久少妇免费视频 | 亚洲精品中文字幕视频 | 亚洲三级网站 | 国产一二区在线观看 | 欧美激情综合网 | 午夜色婷婷 | 欧美成人区| 丁香av| www黄色软件| 国产美腿白丝袜足在线av | 国产精品手机在线播放 | 中文字幕日韩电影 | 精品国产乱码久久久久久久 | 最近中文字幕国语免费av | 中文字幕亚洲精品在线观看 | 国产色婷婷| 中文字幕免费看 | 97**国产露脸精品国产 | 精品国产伦一区二区三区观看体验 | 欧美aaa级片| 亚洲精品电影在线 | 日韩精品久久中文字幕 | 美女国产网站 | 久久精品久久精品久久39 | 天天干 夜夜操 | 成年人在线免费视频观看 | 国产精品一区二区白浆 | 欧美精品在线观看 | 久久国语露脸国产精品电影 | 欧美日韩不卡一区二区 | 国产精品国产亚洲精品看不卡 | 欧美国产精品久久久久久免费 | 国产精品美女久久久网av | 在线观看日韩 | 国产不卡在线视频 | 伊人春色电影网 | 国产成人精品一区二三区 | 国产午夜三级一区二区三 | 欧美日韩免费在线观看视频 | 日韩三区在线 | 国产91成人在在线播放 | 在线日本看片免费人成视久网 | 国产精成人品免费观看 | 久久久一本精品99久久精品 | 视频国产在线观看18 | 成人免费xyz网站 | 国产成人在线观看免费 | 青青草国产免费 | 又黄又爽又湿又无遮挡的在线视频 | 看片在线亚洲 | 亚洲女在线 | 91在线播放视频 | 国产精品3| 天堂麻豆 | 88av色| 国产成人精品三级 | 国产区免费 | 天天操网址 | 国产一区二区在线免费播放 | 色噜噜狠狠色综合中国 | 天天插综合 | 久久人人爽人人爽人人片av免费 | 精品九九久久 | 日本在线精品视频 | 欧美成人亚洲 | 天天插视频 | 国产在线播放观看 | 有码中文在线 | 三上悠亚一区二区在线观看 | 国产精品毛片 | 99色在线观看 | 国产精品麻豆三级一区视频 | 中文字幕一区二区三区精华液 | 亚洲精品视频中文字幕 | 成人理论在线观看 | 久草网站| 91麻豆国产 | 午夜视频不卡 | 亚洲国产精久久久久久久 | 99久久精品国产一区二区三区 | 日本91在线 | 国产成人av一区二区三区在线观看 | 免费看黄在线 | 2021国产在线| 天天色婷婷 | 手机看片 | 国产不卡在线观看 | 成人动态视频 | 国产精品99久久久久久武松影视 | 免费看片网页 | a天堂免费| 欧美日韩精品在线一区二区 | 国产精品一区二区美女视频免费看 | 国产麻豆视频免费观看 | 91精品国产一区 | 色视频一区 | 中文视频在线播放 | 九九九免费视频 | 国产精品99精品久久免费 | 久久久久久久久毛片 | 国产午夜视频在线观看 | 亚洲视频 视频在线 | 日韩精品一区二区三区外面 | 日韩va在线观看 | 久久99精品国产麻豆宅宅 | 国产精品乱码高清在线看 | 日韩精品一区二区三区免费观看视频 | 中文字幕在线观看网站 | 天天激情站 | 日韩av在线免费看 | 国产成人av免费在线观看 | 久久精品一区二区三区中文字幕 | 久久av免费 | 韩国在线一区 | 久久福利国产 | 久久久精品成人 | 成年美女黄网站色大片免费看 | 国产原创av在线 | 免费在线观看亚洲视频 | 91在线看网站 | av一级一片 | 99成人免费视频 | 婷婷综合五月天 | 色的网站在线观看 | 色先锋资源网 | 国产剧情一区在线 | 91视频首页 | 国精产品999国精产品视频 | 天天插综合网 | 国产亚洲成av人片在线观看桃 | 五月婷婷色播 | 88av视频| 日韩免费播放 | 超碰大片 | 国产小视频免费在线观看 | 欧美一区在线观看视频 | 久久系列| 久久久www成人免费精品张筱雨 | 98精品国产自产在线观看 | 久久久久久久久福利 | 97超碰中文字幕 | 天天激情站 | 精品国产乱码久久久久久浪潮 | 久久综合色综合88 | 国产色网| 成年人在线观看网站 | 国产精品久久久久久久久久久久久久 | 九色福利视频 | 四虎精品成人免费网站 | 麻花传媒mv免费观看 | 精品国产免费观看 | 91在线操 | 久久精品99久久 | 久精品视频在线观看 | 国产一区二区高清不卡 | 国产 日韩 中文字幕 | 香蕉视频在线视频 | 最新av电影网址 | 欧美在线视频a | 九九久 | 国产免费xvideos视频入口 | 久久a久久| www.伊人网 | 精品主播网红福利资源观看 | 久久免费久久 | 在线观看av中文字幕 | 天天摸天天操天天爽 | 成人av一级片 | 国产一级电影免费观看 | 久久草精品 | 特及黄色片| 综合久久影院 | 国产精品一区二区中文字幕 | 欧美天堂视频在线 | 国产免费av一区二区三区 | 久久成人免费视频 | 在线精品亚洲一区二区 | 91亚洲国产成人久久精品网站 | 国产精品视频999 | 久久9999久久免费精品国产 | 精品亚洲男同gayvideo网站 | 日p在线观看| 国产一区二区高清 | 天天干,狠狠干 | 亚洲精品一区二区三区高潮 | 久久99亚洲精品久久 | 麻花传媒mv免费观看 | 国产精品婷婷午夜在线观看 | 人人射av| 美女黄频在线观看 | 中文字幕亚洲欧美日韩 | 91在线观看欧美日韩 | 91高清免费在线观看 | 在线观看精品国产 | 97福利| 中文字幕中文 | 免费在线国产精品 | 免费亚洲精品视频 | 狠狠干夜夜爽 | 在线免费观看的av网站 | 日本高清免费中文字幕 | 日韩高清在线观看 | 欧美日韩一区二区在线 | 97综合视频 | 色婷婷综合视频在线观看 | 波多野结衣视频一区二区 | 亚州性色 | 久久亚洲综合色 | 欧美精品三级在线观看 | 中文字幕欧美三区 | 天天曰天天干 | 色天天综合网 | 久久影视精品 | 黄av在线 | 五月婷婷在线播放 | 97精品电影院 | 日韩视频一区二区在线观看 | 国产精品乱看 | 午夜精品区 | 久久久www成人免费毛片 | 美女视频黄网站 | 99精品视频免费观看视频 | 欧美精品一区二区三区四区在线 | 亚洲高清视频一区二区三区 | 欧美色综合天天久久综合精品 | 久久婷婷久久 | 国外av在线 | 久久影院精品 | 国产精品免费视频观看 | 精品嫩模福利一区二区蜜臀 | 成年人免费在线播放 | 国产视频一区在线播放 | 日日爱视频 | 丝袜+亚洲+另类+欧美+变态 | 成人av免费在线播放 | 免费观看国产精品视频 | 成人一级片在线观看 | 日韩精品中字 | 精品福利视频在线 | 99久久精品国产欧美主题曲 | 久久精品伊人 | 搡bbbb搡bbb视频 | 精品91视频 | 精品国产伦一区二区三区观看说明 | 国产欧美精品xxxx另类 | 国产精品2018| 精品美女久久久久久免费 | 国产黄a三级三级 | 亚洲黄色精品 | 五月婷婷网站 | 国产精品久久久久久久久久99 | 四虎成人精品 | 91av资源在线| 免费在线成人av电影 | 黄色一级在线免费观看 | 五月婷婷黄色网 | 不卡av电影在线观看 | 中文字幕欧美激情 | 色瓜 | 999久久久免费视频 午夜国产在线观看 | 日韩在线免费高清视频 | a级成人毛片 | 五月天婷婷在线播放 | 国产精品亚洲片在线播放 | 五月婷婷,六月丁香 | 精品欧美一区二区精品久久 | 特级免费毛片 | 久久久久久久久久网站 | 麻豆视频免费入口 | 日韩精品视频第一页 | 四虎国产精品免费观看视频优播 | 中文字幕在线视频一区二区 | 日日操网站 | 狠狠干夜夜操 | 96久久久 | 日韩和的一区二在线 | 在线播放精品一区二区三区 | 国产成人久久精品77777 | 不卡在线一区 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 国产黄色片免费在线观看 |