上层建筑都是来源基础。基础没学好的情况下。去猜测基础的内容是什么并不可靠。
windows操作系统还是要学的。
windows操作系统还是要学的。
解决方案 »
- winform下,如何将hashtable的数据绑定到listbox中
- winform中datagridview怎么用comobox控件进去啊
- ImageList中的图片地址
- 如何将网页上的控件“搬”到自己的WinForm(C#)中?。。
- C#咋优化呢?
- 字符串转化为二机制的问题
- 求一个关于数字字符串格式的函数!! 急!!!!
- treeview中checkbox设为true以后,每次为了获取所选中的节点,是不是只有必须 通过遍历才能得到啊?
- 一个又棘手又怪的问题!!!
- C#初学者的困惑!难解啊·······
- Winform, webbrowser, 怎样实现将窗体内其他控件的内容拖放到webbrowser中?或者相反?
- 在winform中怎样调用html里的js函数
/// <summary>
/// 查看天气情况
/// </summary>
/// <param name="args">相关参数</param>
public void CheckWeather(MyEventArgs args)
{
// 可以帮收衣服的人开始监听天气
//this.OnWeatherIsRainy(args);
if(this.OnWeatherIsRainy!=null)
{
this.OnWeatherIsRainy(args);
}
}
namespace 收衣服
{ /// <summary>
/// 天气情况枚举
/// </summary>
public enum EnmWeather
{
Rainy,
Sunny
} /// <summary>
/// 定义一个委托
/// </summary>
public delegate void WeatherHandler(); /// <summary>
/// 人
/// </summary>
public class Person
{
private string name; public string Name
{
get { return name; }
} public Person(string name)
{
this.name = name;
} /// <summary>
/// 下雨事件
/// </summary>
public event WeatherHandler OnWeatherIsRainy; /// <summary>
/// 看看天空,是否下雨
/// </summary>
public void LookAtTheSky()
{
// 可以帮收衣服的人开始监听天气
if (this.OnWeatherIsRainy != null)
this.OnWeatherIsRainy();
} /// <summary>
/// 提出帮收衣服的要求的方法
/// </summary>
public void CallForHelp()
{
if (Program.weather == EnmWeather.Rainy)
{
Console.WriteLine("今天是【{0}】,【{1}】提出帮收衣服的要求 o(╯□╰)o ", "雨天", this.Name);
}
else
{
Console.WriteLine("今天是【{0}】,【{1}】不需要收衣服 ~O(∩_∩)O~", "晴天", this.Name);
}
} } class Program
{
/// <summary>
/// 当天的天气情况
/// </summary>
public static EnmWeather weather;
static void Main(string[] args)
{ Person plmm = new Person("漂亮MM");// new一个“漂亮MM”出来
Person me = new Person("我");// new一个“我”出来
plmm.OnWeatherIsRainy += new WeatherHandler(me.CallForHelp); // 漂亮MM接收到【我】提出的帮收衣服的委托
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 注意,这里new了5个情敌,又各向漂亮MM提出了要帮自己收衣服的请求
for (int n = 0; n < 5; n++)
{
Person person = new Person(string.Format("情敌{0}", n));
plmm.OnWeatherIsRainy += new WeatherHandler(person.CallForHelp); // 漂亮MM接收到【我的一堆情敌】提出的帮收衣服的委托
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
int i = 0;
Console.WriteLine("执行结果:");
Console.WriteLine();
while (i < 2)
{
if (i++ % 2 == 0)// 虚拟一个下雨的条件
{
weather = EnmWeather.Rainy;// 下雨啦
}
else
{
weather = EnmWeather.Sunny;// 不下雨那就放晴吧o(╯□╰)o
}
Console.WriteLine("现在是{0}号:", i);
// 漂亮MM抬头看天查看天气情况(事件需要监听,这个方法就是用来监听事件的)
plmm.LookAtTheSky();
Console.WriteLine();
}
Console.WriteLine("按任意键退出:");
Console.ReadKey();
}
}
}
// 执行结果:// 现在是1号:
// 今天是【雨天】,【我】提出帮收衣服的要求 o(╯□╰)o
// 今天是【雨天】,【情敌0】提出帮收衣服的要求 o(╯□╰)o
// 今天是【雨天】,【情敌1】提出帮收衣服的要求 o(╯□╰)o
// 今天是【雨天】,【情敌2】提出帮收衣服的要求 o(╯□╰)o
// 今天是【雨天】,【情敌3】提出帮收衣服的要求 o(╯□╰)o
// 今天是【雨天】,【情敌4】提出帮收衣服的要求 o(╯□╰)o// 现在是2号:
// 今天是【晴天】,【我】不需要收衣服 ~O(∩_∩)O~
// 今天是【晴天】,【情敌0】不需要收衣服 ~O(∩_∩)O~
// 今天是【晴天】,【情敌1】不需要收衣服 ~O(∩_∩)O~
// 今天是【晴天】,【情敌2】不需要收衣服 ~O(∩_∩)O~
// 今天是【晴天】,【情敌3】不需要收衣服 ~O(∩_∩)O~
// 今天是【晴天】,【情敌4】不需要收衣服 ~O(∩_∩)O~// 按任意键退出:
/// 提出帮收被子的要求的方法
/// </summary>
public void PickQuilts()
{
if (Program.weather == EnmWeather.Rainy)
{
Console.WriteLine("今天是【{0}】,【{1}】提出帮收被子的要求 o(╯□╰)o ", "雨天", this.Name);
}
else
{
Console.WriteLine("今天是【{0}】,【{1}】不需要收被子 ~O(∩_∩)O~", "晴天", this.Name);
}
} /// <summary>
/// 提出帮关窗户的要求的方法
/// </summary>
public void CloseWindows()
{
if (Program.weather == EnmWeather.Rainy)
{
Console.WriteLine("今天是【{0}】,【{1}】提出帮关窗户的要求 o(╯□╰)o ", "雨天", this.Name);
}
else
{
Console.WriteLine("今天是【{0}】,【{1}】不需要关窗户 ~O(∩_∩)O~", "晴天", this.Name);
}
}然后将箭头内的那段替换成(详细请看注释): // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 委托是一系列具有同样方法签名的方法模板,PickClothes(),PickQuilts(),CloseWindows()都是参数个数为零,返回值为空的,可以把它们视为具有相同模板,也就是说,下雨了,可以委托MM帮收衣服,也可以委托帮收被子,也可以委托帮关窗户,当然还要吧委托别的,只要这个方法的签名跟委托一致
Person personA = new Person("情敌甲");
Person personB = new Person("情敌乙");
Person personC = new Person("情敌丙");
plmm.OnWeatherIsRainy += new WeatherHandler(personA.PickClothes); // 漂亮MM接收到【情敌甲】提出的帮收衣服的委托
plmm.OnWeatherIsRainy += new WeatherHandler(personB.PickQuilts); // 漂亮MM接收到【情敌乙】提出的帮收被子的委托
plmm.OnWeatherIsRainy += new WeatherHandler(personC.CloseWindows); // 漂亮MM接收到【情敌丙】提出的帮关窗户的委托
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
using System;
using System.Linq;namespace RainAndCallMM
{
public delegate void Mydelegate(); //先定义一个委托类 class me //我
{
public event Mydelegate CallNeighbor;
public void NotifyNeighbor() //邻居MM们告诉我如何通知她我就如何通知她
{
if (CallNeighbor != null) //她跟我说了我才去通知,如果有1000个MM,我就通知1000个
{
CallNeighbor();
}
} public void Rain()
{
Console.WriteLine("下雨了");
NotifyNeighbor();
}
}
class Neighbor //邻居
{
public me m;
public Neighbor(me m)
{
this.m = m;
GreetMe(); //构造函数订阅事件
}
public void GreetMe() //先跟说帅锅下雨要跟我打招呼
{
m.CallNeighbor += TellMe;
} public void TellMe() //帅锅通知我了
{
Console.WriteLine("哦,隔壁的帅锅来提醒我收衣服了。");
}
} class Program
{
static void Main(string[] args)
{ me m = new me(); //帅锅 Neighbor n1 = new Neighbor(m);
Neighbor n2 = new Neighbor(m);
m.Rain(); Console.ReadKey();
}
}}
初学者接触的委托,不管是事件的处理程序,还是Lambda,匿名委托,都只是在别人的框架基础上实现自己的逻辑,只接触了委托的一半概念。而这样的后果是颠倒代码的实现次序,让初学者搞不清调用过程。
这个时候业务逻辑的需求都未定呢, 你怎么开发呢? 所以你想到了使用委托.比如你开发完的这个DLL就叫做 socket.dll 那么好了.接下来... 你可以把这个DLL提供给 研发1部使用. 他们的某个程序内需要使用socket通信. 于是他们在设计完了业务逻辑之后调用你的dll,实现一个委托方法.完成了sokcet消息的接收 一切搞定.然后过了几天, 你又把这个DLL提供给研发2部使用.........
-------------------------于是, 你联想到了什么?
你想起来没, C#的button控件不就是这样吗 button 让你实现他的 button 事件. 他为什么会这么设计?因为他的设计符合我上面的原则:
1,为了提供给后续的开发者使用,而他自己只实现了最基本的逻辑功能
2,他的逻辑是: 把操作系统的鼠标事件透传给业务层,而我的举例是socket.dll把soeckt消息透传给业务层
3,都是为了给将来的 研发1部... 研发2部 使用的...
有时,委托不是为了调用
有时,事件是为是通知
虽然,最终还是调用
http://www.chhblog.com/Web/ArticleView.aspx?ArticleID=172
C#的'委托'功能是很强大的, 它不是单纯的一个函数换个方式来调用. 它内含线程安全的.
可视控件的操作线程只能够是主线程, 其他线程想操作这控件时, 怎么办? 委托帮你办, 并且你可以无视跨线程, 在这个委托未完成之间, 你的子线程可以自动休眠等待, 通过委托, 让多线程的UI编写就像是单线程一样.委托的功能不是那么简单的, 多学习点吧.