我谈Silverlight架构和模式运用1-- ModelView模式最简单教程-讲解无代码触发事件,以及类型转换器的强大功能

大家应该都知道当今Silverlight软件开发中有几种比较流行的架构或者模式,比如:MVC,MVP,MVVM,三层架构,modelView模式.

这篇就先讲解modelview模式.
我看了几个老外写的ModelView模式,不是太好理解,所以吸取好的,按照我的理解,我的思路写出来.
 
大家如果能看懂我写的,我会很高兴的,写文章力求大家都可以读懂.
 
上图:
 
 
功能超级简单,输入你的名字,点击button,会出现一个笑脸,同时显示一段文字.
如果把checkbox前对的 "勾"去掉,
图片就会变成下面的:
 
 
 

其实这个功能大家应该都会实现,很简单,因为简单,我才选为demo讲解的.
 
一般做法:

    private void helloButton_Click(object sender, RoutedEventArgs e) {
            
string greeting;
//初始化 文本框默认显示的内容
            
if (String.IsNullOrEmpty(nameTextBox.Text)) {
                greeting 
= "Hello World!";
            }
            
else {
                
string greetingFormat;
//根据checkbox是否选中来判断文本框是现实开心的内容还是不开心的内容
                
if (happyCheckBox.IsChecked == true) {

                    greetingFormat 
= "Hey! Thanks for stopping by {0}!";//开心
                }
                
else {
                    greetingFormat 
= "Sorry to hear that, {0}. Hope things turn around soon!";//不开心
                }

                greeting 
= String.Format(greetingFormat, nameTextBox.Text);
            }

            greetingLabel.Text 
= greeting;
//如果开心就把开心的图片显示出来,同时把伤心的图片隐藏起来,
如果不开心:.........................................................
            
if (happyCheckBox.IsChecked == true) {
                happyImage.Visibility 
= Visibility.Visible;
                sadImage.Visibility 
= Visibility.Collapsed;
            }
            
else {
                happyImage.Visibility 
= Visibility.Collapsed;
                sadImage.Visibility 
= Visibility.Visible;
            }
是不是很简单,同样用modelview模式也简单.如下:


modelview做法

Silverlight基本是面向对象的全程开发,啥事情都和类相关,蛮爽的 ,呵呵,所以viewmodel模式当然也离不开类.
所以我们先定义一个类:
这个是简略图:只把字段列出来,属性没有写出来,详细大家自己看具体demo
 
public class HelloWorldViewModel : INotifyPropertyChanged {

        
private string _name;
        
private bool _happy = true;
        
private string _greeting = "Hello";
}
前台代码和类中的某个属性进行绑定语句:

textblock和Greeting属性进行绑定

 <TextBlock x:Name="greetingLabel" HorizontalAlignment="Center" FontSize="24"
        Text
="{Binding Greeting}"
        TextWrapping
="Wrap" />

checkbox和ishappy属性进行绑定
 
 <CheckBox x:Name="happyCheckBox" Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Center"
          Content
="I'm Happy!" IsChecked="{Binding IsHappy, Mode=TwoWay}" />
前面已经绑定好了,下面看触发事件,这里以button为例,点击button后,触发事件.

后台只需要控制类的属性值变化,就会使得前台也跟着变

(这就是绑定的奥秘,也是依赖属性的奥秘,后台代码变,前台自动变,可以不用了解依赖属


性,Silverlight3都封装好了)

下面看看如何使得 后台属性值变化,前台自动跟着变化:



点击button 我要实现的是 上面两个控件根据属性值变化使得界面也跟着变化,也就是textblock控

件根据是否开心显示不同的内容.

同时图片也根据checkbox选择的不同显示是笑脸还是哭脸.

 这里注意:没有button事件,整个后台cs文件里面什么都不用写,空空兮.


button的前台代码:


  <Button x:Name="helloButton" Grid.Row="2"
          HorizontalAlignment
="Right" VerticalAlignment="Center" Width="75" Height="23"
          Content
="Hello" app:Commands.Command="{Binding HelloCommand}" 


看看上面的代码,绑定的是?? 对了 ,绑定的是命令,是一个方法.

可以这样认为:绑定的是方法,也即是点击button会自动执行某个方法,


不用再去写什么点击事件,在时间里面定义处理语句了.


 //这是点击button要实现的事件内容
 public void Hello() {
            
if (String.IsNullOrEmpty(Name)) {
                Greeting 
= "Hello World!";
            }
            
else {
                
string greetingFormat;

//前面我们把Greeting 这个属性和textblock属性绑定了,后台变则前台也会变的.
                
if (IsHappy == true) {
                    greetingFormat 
= "Hey! Thanks for stopping by {0}!";
                }
                
else {
                    greetingFormat 
= "Sorry to hear that, {0}. Hope things turn around soon!";
                }

                Greeting 
= String.Format(greetingFormat, Name);
            }
        }
   下面是实现无代码编程的关键所在,不理解记住也行啦,反正我刚开始就不理解,用的多了才去慢慢研究底层是怎么实现的.
     //这里其实是一个委托(委托毕竟是类的一个成员,所以当然可以绑定啦)
        
//只是被封装好了,方便大家调用而已.
        private DelegateCommand _helloCommand;
        
//下面是实现将委托和委托要执行的方法挂钩,这里和我们上面定义的hello方法挂钩.
        public ICommand HelloCommand {
            
get {
                
if (_helloCommand == null                    _helloCommand = new                }
                
return            }
 
好了,这样我们就实现了无代码触发鼠标事件了.
转换器的用法:

对了其实图片的隐藏与显示还用到了转换器:
这里说一下:大家一定就明白啥回事了,
前面提到 后台变前台也变,其实后台变的时候 前台在变化之前如果绑定语句中绑定了转换器,是会先执行转换器中的语句的.
晦涩的话不能说太多,以例子为中心讲解,先看前台是如何绑定转换器的:
第一步:定义一个转换器(就是一个类),转换器实现的功能是根据控件绑定的属性的值自动显示或者隐藏:

  public class BoolToVisibilityConverter : IValueConverter {

        
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            
if (parameter == null) {
                
return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;
            }
            
else {
                
return ((bool)value) ? Visibility.Collapsed : Visibility.Visible;
            }
        }

        
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            
throw new NotImplementedException();
        }
第二步:将转换器引用进来,可以将其放置于资源里面(定义一次,重复使用)
 <UserControl.Resources>
    
<app:BoolToVisibilityConverter x:Key="boolToVisibility" />
  
</UserControl.Resources>
 
 
第三步:绑定
  <Image x:Name="happyImage" Source="/Images/Happy.jpg"
      Visibility="{Binding IsHappy, Converter={StaticResource boolToVisibility}}"/>
    
<Image x:Name="sadImage" Source="/Images/Sad.jpg"
      Visibility
="{Binding IsHappy, Converter={StaticResource boolToVisibility}, ConverterParameter='Invert'}" />
 
绑定好了之后,只要属性值被修改了,前台在显示之前都会过"转换器这一关".
 
大家知道 2.0 版本的数据的验证都是用转换器做的,还有日期格式的转换也是用转换器做的,所以大家可以
简单的认为他就是一个转换器,它的功能要发散使用.
 
我们企业级项目就是用转换器实现从数据中取出数据之后 格式化一些日期的:
比如:日期从数据库中取出来是:2009/09/09:10:12:23,通过转换器可以转换成我们想要的格式.
所以一定要理解掌握哦!
 
还是那句话,我们项目用到的我不可以上传,但是我可以找相似的demo上传给大家,并且详细讲解.
 
 
 

 

posted @ 2009-09-27 19:16  书奎  阅读(1834)  评论(10编辑  收藏  举报