距離上篇寫的時間有1年多了.wpf太大,寫的東西實在太多,我將依然圍繞著自定義控件來展開與其相關的技術點. 也歡迎大家參與討論.這篇我們將要討論的是WPF依賴屬性,接觸過的朋友應該對其有所了解,但在我們講WPF依賴屬性之前,我們來看看在WPF出現之前.net中的屬性是如何使用的.
普遍存在的屬性問題
c#基本屬性
ASP.NET自訂控制項屬性
WinForm自訂控制項屬性
Javascript自訂控制項屬性
c#基本屬性
namespace WPFControlTutorialPart2_Basic
{
public class Person
{
private string _name;
public string Name
{
get { return _name; }
設置 { _name = 值; }
}
//自動屬性
public int Age { get; set; }
}
}
上面應該算是c#的最基礎的屬性,大家都很熟悉.
注意點:預設屬性沒有初始化,不然可能會發生很多未知的錯誤.
(以下可以選看,如果你接觸過以下技術的話,其實也很簡單)
ASP.NET自訂控制項屬性
namespace WPFControlTutorialPart2_WebApp
{
public class WebFromControl : WebControl
{
private string _controlName;
public string ControlName
{
get
{
return _controlName;
}
set
{
_controlName = value;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write("控制項名稱是:"+ControlName);
}
}
}
上面是一個簡單的自訂的Web伺服器控制項.
asp.net控制項著重在於呈現,每次刷新頁面都將會呼叫RenderContents方法,這樣就不管屬性有沒發生變化,都將得到重新呈現.即此處不需要屬性發生變化,進行UI重繪通知.
注意點:如果強制要求ControlName屬性必須是有值的,以確保輸入結果的有效性,那麼可以在get方法裡處理
get
{
if (_controlName == null) _controlName = string.Empty;
return _controlName;
}
WinForm自訂控制項屬性
當屬性改變時並未重繪,必須手動呼叫Invalidate方法以進入OnPaint方法重繪
注意點:如果要重繪介面的話,必須手動呼叫方法
JavaScript自訂控制項屬性
<div id="demoDiv" style="background-color: Red">hello</div>
<script>
function ElementControl(elementName) {
this.element = document.getElementById(elementName);
}
ElementControl.prototype.setWidth = function(width) {
this.element.style.width = width;
}
var obj = new ElementControl("demoDiv");
obj.setWidth("hello");
</script>
javascript的變數型別沒有強型別,例如設定dom的寬度,其型別只能是整數,如果以字串進行傳值的話將會出錯(當然這是人為的).
(不知道做過js前端控制的人有沒這種感覺,定義了一個屬性然後重新賦值重繪控制項是一件痛苦的事,必須手動調動,而且會影響整個控制設計.)
注意點:要對於屬性的賦值的有效性進行驗證.
從以上幾個例子,我們可以看出單純的屬性是無法滿足程式需求的.
既以上的需求是有必要的,並且常常發生,而且非常頻繁.
標準化解決方案
以上介紹了屬性存在的一系列問題,那麼有問題就會有簡化的方案.
以下是個人總結的話
當一項技術比較複雜的時候,就會有人出來定義一套標準,以簡化技術,提高生產效率.
不管設計者考慮的如何周密,一旦標準定義下來,就會喪失彈性.
標準可能與你個人習慣想衝突,你必須去學會接受標準回到WPF話題,那麼在WPF中這個解決方案就是依賴屬性(DependencyProperty)
好了,這篇只是一個引子,如果你在使用屬性時,遇到過這些問題,那麼你將有所感觸.
如果你有認知到屬性真實存在以上問題,那麼這篇文章就算完成任務了.
這篇並不打算展開.下篇將再次介紹WPF依賴屬性系統
歡迎大家展開討論.