之前只是简单的介绍了一下ModelLocator的用法,在这里要把模型和视图结合起来,通过模型来来控制视图。在Silverlight中我们可以看到所有新建立的xaml都是继承自UserControl,所以在这里更新欢称视图为控件。 至此给出一个项目的结构图出来。这里我是习惯把从网上下载的第三方类库放在项目中一个Lib的目录下,如果有源码的话直接加入解决方案中也是可以的。
为控件创建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