点击这里给我发消息 点击这里给我发消息
首页 > 行业资讯 > flash>详细内容

Silverlight自定义控件开发 - 令人懊恼的OnApplyTemplate问题

添加时间:2010-6-22
    相关阅读: 开发 模板 Windows

继承自System.Windows.Controls.Control是不知什么时候调用OnApplyTemplate方法的,这就有可能给你制造麻烦,例如,开发了一个PathButton控件,XAML中定义一个了Path对象,然后定义了Data这个属性,让使用者可以设置Path的Data,

        /// <summary>
        /// Gets or sets the data.
        /// </summary>
        /// <value>The data.</value>
        public string Data
        {
            get { return (string)GetValue(DataProperty); }
            set
            {
                SetValue(DataProperty, value);

                PathElement.Data = Services.PathGeometryParser.Parse(value);
            }
        }

  其它地方使用这个控件

  PathButton bt = new PathButton();

  bt.Data = "....";

  NullReferenceException

  解决的方法就是在PathButton的构造函数里就进行加载模板,然后调用ApplyTemplate方法。下面是我的实现方法,代码很简单

 1     /// <summary>
 2     /// XControl
 3     /// </summary>
 4     public class XControl : Control
 5     {
 6         /// <summary>
 7         /// True表示已经应用过模板
 8         /// </summary>
 9         protected bool _TemplateApplied;
10 
11         /// <summary>
12         /// 初始化组件
13         /// </summary>
14         protected virtual void InitializeComponent()
15         {
16             var objStyle = GetStyle(this.DefaultStyleKey as Type);
17             if (objStyle != null)
18             {
19                 this.Style = objStyle;
20                 this.ApplyTemplate();
21             }
22         }
23         /// <summary>
24         /// 请重写此方法代替OnApplyTemplate
25         /// </summary>
26         protected virtual void OnApplyXTemplate()
27         {
28 
29         }
30         /// <summary>
31         /// 请重写OnApplyXTemplate方法代替
32         /// </summary>
33         public override sealed void OnApplyTemplate()
34         {
35             if (this._TemplateApplied)
36                 return;
37             this._TemplateApplied = true;
38             this.OnApplyXTemplate();
39         }
40 
41         #region Static Methods
42         /// <summary>
43         /// 样式字典集合
44         /// </summary>
45         private static System.Collections.Generic.Dictionary<Type, ResourceDictionary> _ResourceDictionarys =
46             new System.Collections.Generic.Dictionary<Type, ResourceDictionary>();
47         /// <summary>
48         /// 获取样式
49         /// </summary>
50         /// <param name="styleKey"></param>
51         /// <returns></returns>
52         static public Style GetStyle(Type styleKey)
53         {
54             var rd = GetResourceDictionary(styleKey);
55             if (rd != null)
56             {
57                 string strKey = styleKey.ToString();
58                 if (rd.Contains(strKey))
59                     return rd[strKey] as Style;
60             }
61             return null;
62         }
63         /// <summary>
64         /// 获取样式字典
65         /// </summary>
66         /// <param name="styleKey"></param>
67         /// <returns></returns>
68         static public ResourceDictionary GetResourceDictionary(Type styleKey)
69         {
70             if (_ResourceDictionarys.ContainsKey(styleKey))
71                 return _ResourceDictionarys[styleKey];
72 
73             string fullName = styleKey.Assembly.FullName;
74             string baseName = fullName.Substring(0, fullName.IndexOf(",")) + ".g";
75 
76             System.Resources.ResourceManager manager = new System.Resources.ResourceManager(baseName, styleKey.Assembly);
77             System.IO.UnmanagedMemoryStream stream = null;
78             try
79             {
80                 stream = manager.GetStream("themes/generic.xaml", System.Globalization.CultureInfo.CurrentUICulture);
81                 string strTemplate = new System.IO.StreamReader(stream).ReadToEnd();
82                 var rd = System.Windows.Markup.XamlReader.Load(strTemplate) as ResourceDictionary;
83                 _ResourceDictionarys.Add(styleKey, rd);
84                 return rd;
85             }
86             catch { }
87             finally
88             {
89                 stream.Dispose();
90             }
91             return null;
92         }
93         #endregion
94     }

1     public class PathButton2 : XControl
 2     {
 3         public PathButton2()
 4         {
 5             this.DefaultStyleKey = typeof(PathButton);
 6             //初始化组件
 7             base.InitializeComponent();
 8         }
 9         /// <summary>
10         /// 重写OnApplyXTemplate代替OnApplyTemplate方法
11         /// </summary>
12         protected override void OnApplyXTemplate()
13         {
14             base.OnApplyXTemplate();
15         }
16     }
17 

  通过继承XControl的自定义控件与System.Windows.Controls.Control不同在于,需要重写OnApplyXTemplate代替OnApplyTemplate方法,然后在构造函数里设置DefaultStyleKey后手动调用InitializeComponent方法。

本文作者:未知
咨询热线:020-85648757 85648755 85648616 0755-27912581 客服:020-85648756 0755-27912581 业务传真:020-32579052
广州市网景网络科技有限公司 Copyright◎2003-2008 Veelink.com. All Rights Reserved.
广州商务地址:广东省广州市黄埔大道中203号(海景园区)海景花园C栋501室
= 深圳商务地址:深圳市宝源路华丰宝源大厦606
研发中心:广东广州市天河软件园海景园区 粤ICP备05103322号 工商注册