天天看點

改變元件設計時行為 - 凡丁

改變元件設計時行為

在設計時,

看看TextBox控件,Multiline屬性設定為false時隻能左右方向改變大小,這是怎麼實作的呢?

我自定義了一個控件,想要一些屬性不顯示在屬性對話框裡,該怎麼辦呢?

在DataGrid控件的右鍵菜單裡會比其它控件多一項“自動套用格式(A)”,我可以做到類似的功能嗎?

請看這裡

關鍵字:WinForm Designer DesignTime Attribute 元件 控件 開發 設計時

在設計時,

看看TextBox控件,Multiline屬性設定為false時隻能左右方向改變大小,這是怎麼實作的呢?

我自定義了一個控件,想要一些屬性不顯示在屬性對話框裡,該怎麼辦呢?

在DataGrid控件的右鍵菜單裡會比其它控件多一項“自動套用格式(A)”,我可以做到類似的功能嗎?

使用.net提供的Designer特性,您可以為元件指定設計器,通過自定義的設計器,我們可以很友善的改變元件設計時的行為。在.net中,所有設計器都要實作IDesigner接口。要實作自己的設計器,您可以實作IDesigner接口或直接從已有的設計器類繼承如ComponentDesigner類。

接下來我們用一個實際的例子來說明如何建立自己的設計器并實作上述功能,在本文的例子裡我選擇由ControlDesigner類繼承來實作自己的設計器,它是繼承自ComponentDesigner類的。檢視它的成員清單可以發現,ControlDesigner定義了一個SelectionRules隻讀屬性,該屬性可以實作控制控件在某個方向上改變大小的功能。

下面我們就來實作一個自定義的設計器:

public class LabelLineDesigner : System.Windows.Forms.Design.ControlDesigner

{

    public LabelLineDesigner():base()

    {}

    /**//// <summary>

    /// 重載SelectionRules屬性自定義選擇規則

    /// </summary>

    public override SelectionRules SelectionRules

    {

        get

        {

            SelectionRules selectionRules = SelectionRules.Moveable | SelectionRules.Visible | SelectionRules.LeftSizeable | SelectionRules.RightSizeable;

            return selectionRules;

        }

    }

}

OK,我們已經實作了一個簡單的設計器,那麼如何把它應用到控件上呢?請繼續往下看,假設我們自定義了一個名為LabelLine的控件,要應用LabelLineDesigner設計器使用下面方法:

[Designer(typeof(LabelLineDesigner))]//為控件指定設計器

public class LabelLine : System.Windows.Forms.Control

{

    ……

}

此時,如果你在窗體上放置一個LabelLine控件話,你可以看到現在它隻能從左右方向上改變控件的大小了。改變LabelLineDesigner類SelectionRules屬性值的組合,你可以實作一些有趣的功能,比如控件在設計時不能被選擇,如果你想要做一個可視化的報表設計器,這個功能可能會很有用。

現在,這個控件已經不能用滑鼠在上下方向改變大小了,但通過屬性視窗,我們修改控件的Size屬性可以随意改變它的大小,這可不是我希望的。怎麼辦呢?對,把這個屬性藏起來,不讓它出現在屬性視窗上。

不讓一個控件屬性顯示在屬性視窗中,一種方法可以通過IDesignerFilter接口實作,另一種方法可以使用Browable特性。我們一個一個來試。

查了一下SDK文檔,ComponentDesigner提供了IDesignerFilter接口的空實作。我們可以重寫該實作的方法,進而在設計時調整關聯元件的特性、屬性和事件。

/**//// <summary>

/// 重載PostFilterProperties方法隐藏屬性

/// </summary>

protected override void PostFilterProperties(IDictionary properties)

{

    foreach(string prop in unbrowsableProperties)

    {

        properties.Remove(prop);

    }

    base.PostFilterProperties (properties);

}

//想到去掉的屬性

private static readonly string[] unbrowsableProperties = {  "Dock","Size"};

将上面代碼添加到LabelLineDesigner類中,編譯一下,在屬性視窗檢視該控件的屬性,Size和Dock屬性真的不見了。再用滑鼠改變一下控件的大小,你會發現怎麼沒有反應了。怎麼會這樣?

先不管它,再來試Browable特性,在LableLine類中添加下面代碼:

[Browsable(false)]

public new System.Drawing.Size Size

{

    get

    {

        return base.Size;

    }

    set

    {

        base.Size = value;

    }

}

編譯一下,再到屬性視窗檢視,Size屬性不見了,用滑鼠改變控件大小,也沒有問題了。看來這個方法可行。

這兩種方法有什麼差別呢?原來第一種隐藏屬性的方法是将屬性從控件屬性清單中删除,而調整控件大小時需要同時改變Size屬性的值,此時再通路控件的Size屬性時已經不存在,是以控件的大小就不能改變了。而應用Browable特性隻是讓該屬性不顯示在屬性視窗裡,并不删除該屬性。即第一種方法是删除屬性而不是隐藏屬性。

接下來,我想在自定義控件的右鍵菜單裡添加一項顯示“關于”對話框的功能,也可以通過LabelLineDesigner來實作,在LabelLineDesigner類中添加如下代碼:

private System.ComponentModel.Design.DesignerVerb verb = null;

        private System.ComponentModel.Design.DesignerVerbCollection _Verbs = null;

public override System.ComponentModel.Design.DesignerVerbCollection Verbs

{

    get

    {

        if (_Verbs == null)

        {

            _Verbs = new System.ComponentModel.Design.DesignerVerbCollection();

            _Verbs.Add(verb);

        }

        return _Verbs;

    }

}

private void OnAbout(object sender, EventArgs args) 

{

    System.Windows.Forms.MessageBox.Show("顯示你的資訊");

}

微軟把Verbs譯成“設計時謂詞”,初次看到這個詞,我實在無法了解它究竟是做什麼的,後來才發現原來在設計時環境中顯示控件右鍵菜單時,會将Verbs屬性的内容關聯到右鍵菜單中,單擊該菜單項時會調用适當的方法,進而在設計時實作一些特殊的功能。另外利用該方法添加到右鍵菜單項目也會同時出現在屬性視窗中。

到此為止,我們前面提到的三個問題都解決了。其實這些内容在SDK文檔中都有介紹,最好的學習資料就在我們手邊,而我們卻經常忽略了它。

下面是我寫的示範程式貼圖 

示範程式在Win2003、.NET Framework 1.1環境下調試通過。示範程式下載下傳

posted on

2005-03-24 16:47 

凡丁 

閱讀(2589) 

評論(1) 

編輯 

收藏 

舉報

改變元件設計時行為 - 凡丁