园子里有很多讲“委托”,“事件”和“接口”的文章,好文章有很多。在这片文章里将结合“Windows Phone”的一个开发实例,.net机制和自己的粗陋的理解来介绍。
首先看实例全部代码:
后台代码:
public class NotepadItem:INotifyPropertyChanged
{
public string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
NotifyPropertyChanged("Title");
}
}
public string _intro;
public string Intro
{
get { return _intro; }
set
{
_intro = value;
NotifyPropertyChanged("Intro");
}
}
public string _cont;
public string Cont
{
get { return _cont; }
set
{
_cont = value;
NotifyPropertyChanged("Cont");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
前台XAML代码:
<controls:Pivot Title="手机保险箱">
<!--Pivot item one-->
<controls:PivotItem Header="秘密记事本">
<!--Double line list with text wrapping-->
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="FirstListBox_SelectionChanged" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding Intro}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
开始分析,Let go...
这段代码实现的功能:将信息绑定到Listbox控件,当数据源信息发生改变时,页面上展示的信息也跟着改变。(功能简单吧,主要介绍“委托”、“事件”和“接口”)
一、“INotifyPropertyChanged”接口(Interface)
// Summary:
// Notifies clients that a property value has changed.
public interface INotifyPropertyChanged
{
// Summary:
// Occurs when a property value changes.
event PropertyChangedEventHandler PropertyChanged;
}
“接口”就是一套标准,然后由“实现类”实现其中具体的方法,可以理解为一组抽象类。任何类只要实现了这个接口,也就是实现了“PropertyChanged”方法,就可以“做一些事情”。“这些事情”就是指类属性的改变触发些事件。
注意:这里的“任何类”都去继承它,它们都有相同的功能要实现,这样大家都保持了一致。而不是每个人都声明自己的,这样就保证了规范化,要变大家一起变,“接口”的优势,你也可以理解为“模块对接标准”。
二、委托(delegate)
在接口中已经看到"PropertyChangedEventHandler",对它就是一个委托,看看它的定义。
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
当你在一个方法中要调用另一个方法,而它们又不在一个“类”下,甚至不在同一个命名空间下。又或者说你要在一个方法中调用一批方法,这批方法的方法体相似,只有一些属性变量不同。这是笨方法就是使用条件或是枚举进行判断,这样如果又有新的方法加入了怎么办,从新修改判断语句???这就牵扯到项目的可扩展了。这是怎么办比较好呢?把这些方法作为参数直接传入目标方法中,也就是大家说的“将方法作为方法的参数”。
既然方法成了参数,那么参数应该有“参数类型”吧,用于规定方法代表的参数的种类。就像“String” 类型的参数。 这种“方法”类型参数的定义者就是“委托”。委托其实是一个类,虽然定义方法像定义方法似地,所以才可以定义类型吗。编译的时候就变为类了,也正是因为它是一个类,所以才可以在所有声明类的地方声明委托,也就是可以在命名空间里直接声明委托。
这样就可以直接将方法作为参数传入另一个方法里面了,在方法里面只要调用“参数”,就可以调用传入的“方法”。不用在纠结于执行方法的判断了,传什么咱就执行什么。
既然“委托”是类型,那么你自然就可以使用它定义变量了。
比如:这时有两个类,一个“Manager”,一个“Employ”,要在“Manager”中调用“Employ”中的方法怎么办?这时可以声明一个委托“ManagerDelegate”,然后使用这个委托定义一个变量“delegate”,然后把“Employ”中的方法赋值给“deleegate”,再把“delegate”传入“Manager”方法即可。是不是和使用类型的变量方式一样,只不过在委托中一个变量不只可以赋值“一个方法”,还可以“绑定”更多的方法。第一个要赋值“=”,以后绑定“+=”,去除“-=”。
试想,如果我们将“delegate”,变量放入"Manager"类中会怎么样?
加上判断if(delegate!=null){ delegate() //调用委托方法}else{},直接执行“委托定义的变量:delegate”了,那么这个“deltegate”还有个名字你知道就什么吗? 猜对了,就是“事件”。
三:事件(Event)
在变量“delegate”,变身“事件”之前,还要增加一个“Event”关键子,以增强封装性。
一句话,事件是一个进行了封装的委托类型的变量。
这也就是“event PropertyChangedEventHandler PropertyChanged;”中“event”的来历。
总之:接口是“模块对接”标准,要变大家一起变。委托是把“方法”作为参数,对应的参数类型。事件是委托类型定义的再经过“event”封装的变量。
这只是在下鄙陋的理解和看法,肯定有很多不当的地方,还请大家多多指教。
还没有介绍整体的实现流程和.net实现机制,关于这些内容将会在下面作介绍,敬请关注。