基于Cairngorm的Silverlight开发 - part3

使用ModelLocator来管理视图

之前只是简单的介绍了一下ModelLocator的用法,在这里要把模型和视图结合起来,通过模型来来控制视图。在Silverlight中我们可以看到所有新建立的xaml都是继承自UserControl,所以在这里更新欢称视图为控件。

至此给出一个项目的结构图出来。这里我是习惯把从网上下载的第三方类库放在项目中一个Lib的目录下,如果有源码的话直接加入解决方案中也是可以的。

所有的用户控件都是创建在Controls目录下。这里提到了创建用户控件,所以就不得不提一下控件的DependencyProperty属性,他是控件的一个静态的属性,主要用来做数据绑定。

为控件创建DependencyProperty属性

创建了DependencyProperty后能更方便的和ModelLocator进行绑定。处理一些界面上的动画效果也能更加的灵活。
这里给出一个标准的代码
        // Using a DependencyProperty as the backing store for TheName.  
        
// This enables animation, styling, binding, etc
        public static readonly DependencyProperty TheNameProperty =
            DependencyProperty.Register(
"TheName",
                                        
typeof(string),
                                        
typeof(Page),
                                        
new PropertyMetadata("",
                                          
new PropertyChangedCallback(
                                            OnTheNameChanged)));

        
static void OnTheNameChanged(object sender,
                                     DependencyPropertyChangedEventArgs args)
        {
            
// Get reference to self
            Page source = (Page)sender;

            
// Add Handling Code
            string newValue = (string)args.NewValue;
        }
更多关于创建自定义用户控件的请查看winter-cn 前辈的《Silverlight 2 Customized Control 开发》 ,写的非常的详细。(我这里就不再去重复的发明轮子了)

创建一个会变色的控件

这里先看Demo

学习是一个温故知新的过程,之前我写过一篇《动态创建Storyboard》这里就用上他再结合DependencyProperty做一个会变色的控件。


运用DependencyProperty结合Storyboard创建控件
    public partial class BackGorund : UserControl
    {


        
public byte R
        {
            
get { return (byte)GetValue(RProperty); }
            
set { SetValue(RProperty, value); }
        }

        
// Using a DependencyProperty as the backing store for R.  
        
// This enables animation, styling, binding, etc
        public static readonly DependencyProperty RProperty =
            DependencyProperty.Register(
"R",
                                        
typeof(byte),
                                        
typeof(BackGorund),
                                        
new PropertyMetadata((byte)0,
                                            
new PropertyChangedCallback(OnRChanged)));

        
static void OnRChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            
// Get reference to self
            BackGorund source = (BackGorund)sender;

            source.changeColor();
        }



        
public byte G
        {
            
get { return (byte)GetValue(GProperty); }
            
set { SetValue(GProperty, value); }
        }

        
// Using a DependencyProperty as the backing store for G.  
        
// This enables animation, styling, binding, etc
        public static readonly DependencyProperty GProperty =
            DependencyProperty.Register(
"G",
                                        
typeof(byte),
                                        
typeof(BackGorund),
                                        
new PropertyMetadata((byte)0,
                                            
new PropertyChangedCallback(OnGChanged)));

        
static void OnGChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            
// Get reference to self
            BackGorund source = (BackGorund)sender;

            source.changeColor();
        }



        
public byte B
        {
            
get { return (byte)GetValue(BProperty); }
            
set { SetValue(BProperty, value); }
        }

        
// Using a DependencyProperty as the backing store for B.  
        
// This enables animation, styling, binding, etc
        public static readonly DependencyProperty BProperty =
            DependencyProperty.Register(
"B",
                                        
typeof(byte),
                                        
typeof(BackGorund),
                                        
new PropertyMetadata((byte)0,
                                            
new PropertyChangedCallback(OnBChanged)));

        
static void OnBChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            
// Get reference to self
            BackGorund source = (BackGorund)sender;

            source.changeColor();
        }



        
public void changeColor()
        {
            colorAnim.To 
= Color.FromArgb(255, R, G, B);
            storyboard.Begin();
        }



        
private ColorAnimation colorAnim;
        
private Storyboard storyboard;

        
public BackGorund()
        {
            InitializeComponent();

            storyboard 
= new Storyboard();

            Brush br 
= this.LayoutRoot.Background;
            colorAnim 
= new ColorAnimation();
            colorAnim.To 
= Color.FromArgb(255, R, G, B);
            colorAnim.Duration 
= TimeSpan.FromSeconds(1);
            colorAnim.RepeatBehavior 
= new RepeatBehavior(1);
            colorAnim.AutoReverse 
= false;
            Storyboard.SetTarget(colorAnim, br);
            Storyboard.SetTargetProperty(colorAnim, 
new PropertyPath("Color"));
            storyboard.Children.Add(colorAnim);
            Resources.Add(
"colorsb", storyboard);

            
this.Loaded += new RoutedEventHandler(BackGorund_Loaded);
        }
    }
创建ModelLocator
    public class BackGroundModel : ModelLocator
    {
        

        
private static readonly BackGroundModel _instance = new BackGroundModel();

        
public static BackGroundModel Instance { get { return _instance; } }

        
static BackGroundModel()
        {

        }
        
private BackGroundModel()
            : 
base()
        {

        }

        
private byte _R = (byte)0;
        
public byte R
        {
            
get { return _R; }
            
set
            {
                _R 
= value;
                NotifyPropertyChanged(
"R");
            }
        }

        
private byte _G = (byte)0;
        
public byte G
        {
            
get { return _G; }
            
set
            {
                _G 
= value;
                NotifyPropertyChanged(
"G");
            }
        }

        
private byte _B = (byte)0;
        
public byte B
        {
            
get { return _B; }
            
set
            {
                _B 
= value;
                NotifyPropertyChanged(
"B");
            }
        }

    }

控件Load时绑定属性,通过模型来控制视图

        void BackGorund_Loaded(object sender, RoutedEventArgs e)
        {
            
this.DataContext = BackGroundModel.Instance;
            Binding bindR 
= new Binding("R");
            bindR.Mode 
= BindingMode.TwoWay;
            
this.SetBinding(RProperty, bindR);
            Binding bindG 
= new Binding("G");
            bindG.Mode 
= BindingMode.TwoWay;
            
this.SetBinding(GProperty, bindG);
            Binding bindB 
= new Binding("B");
            bindB.Mode 
= BindingMode.TwoWay;
            
this.SetBinding(BProperty, bindB);
        }

 

提高效率

Shawn Wildermuth 写了一个Code Snippets能帮我们快速的创建DependencyProperty属性,具体用法与下载地址请访问这里 。我自己写了一个快速创建ModelLocator的Code Snippets,用法都是一样,点击这里 下载。
送上视频 :) ViewManagerP1.wmv 基于Cairngorm的Silverlight开发 - part2
posted @ 2009-03-15 21:24  王喆(nasa)  阅读(1993)  评论(2编辑  收藏  举报