2013-03-15 95 views
5

我想創建我自己的帶有設計時支持的TabControl類。自定義控件設計時

這是我的設計師

public class TabListDesigner : ParentControlDesigner 
{ 
    protected TabList TabListControl { get { return this.Control as TabList; } } 

    protected override void WndProc(ref Message m) 
    { 
     switch (m.Msg) 
     { 
      case 0x7b: // WM_CONTEXTMENU 
       this.OnContextMenu(Cursor.Position.X, Cursor.Position.Y); 
       break; 
      default: 
       base.WndProc(ref m); 
       break; 
     } 
    } 

    protected override bool GetHitTest(Point point) 
    { 
     return this.TabListControl.HitTest(this.TabListControl.PointToClient(point)) != null; 
    } 

    protected override void OnPaintAdornments(PaintEventArgs pe) 
    { 
     base.OnPaintAdornments(pe); 
     ControlPaint.DrawFocusRectangle(pe.Graphics, this.Control.ClientRectangle); 
    } 

    public override void InitializeNewComponent(IDictionary defaultValues) 
    { 
     base.InitializeNewComponent(defaultValues); 
     this.AddTabListPage(); 
     this.AddTabListPage(); 
    } 

    protected virtual void AddTabListPage() 
    { 
     IDesignerHost host = (IDesignerHost)this.GetService(typeof(IDesignerHost)); 

     if (host != null) 
     { 
      using (DesignerTransaction transaction = host.CreateTransaction(string.Format("Add TabListPage to '{0}'", this.TabListControl.Name))) 
      { 
       try 
       { 
        TabListPage page = (TabListPage)host.CreateComponent(typeof(TabListPage)); 
        MemberDescriptor controlsProperty = TypeDescriptor.GetProperties(this.TabListControl)["Controls"]; 

        this.RaiseComponentChanging(controlsProperty); 

        this.TabListControl.Add(page); 
        this.TabListControl.Controls.Add(page); 

        this.RaiseComponentChanged(controlsProperty, null, null); 

        transaction.Commit(); 
       } 
       catch 
       { 
        transaction.Cancel(); 
        throw; 
       } 
      } 
     } 
    } 
} 

在設計師,我我自定義的Tabcontrol添加到窗體和2個TabPage顯示正常。現在我測試了這個項目,2個Tabpages消失了。我回到設計師那裏,Tabpages已經不存在了。爲什麼?

+1

你試過設置建立一個環境來調試你的設計時間控件?(http://msdn.microsoft.com/en-us/library/ms996457.aspx)幫助你像平常一樣能夠遍歷代碼,可以突出顯示問題很好,如果你遵循流程。 – Amicable 2013-03-15 16:21:09

+0

我認爲問題在於序列化。您的示例在開始時創建了一個帶有2個選項卡的TabList,但這兩個選項卡未被序列化。在表單頭文件中檢查「#pragma region Windows Form Designer生成的代碼」區域。如果你找不到像TabList-> Items-> Add(TabPage1)那樣的東西,然後你的網頁被序列化。 – 2013-04-02 19:42:59

+0

我不知道,但有一件事對我來說很奇怪:先將相同的頁面添加到TabListControl,然後再添加到TabListControl.Controls。 – 2013-07-09 12:08:24

回答

0

我曾經創建過一個控件設計器,而不是表單設計者使用的控件設計器,但更像是一個單一控件的實際表單設計器。我不太記得這個項目,但是我確實記得遇到同樣的問題,我不得不提醒視覺工作室我已經以某種方式改變了價值。

保存設計器選項卡後,Visual Studio將繼續並根據語言將該更改轉換爲代碼,並將其寫入窗體的設計器文件中。你也可以使用codeDom編寫你自己特定的代碼生成器,但這是非常先進的。

這不完全是你想要的,但我敢打賭,問題是相關的,所以忍受着我。我能在該領域找到的唯一例子是一個叫做「形狀設計器」的acient c#項目。我從淺藍色的網站上獲得了它。我做了一些搜索,但我無法找到該頁面。無論如何,代碼都有很好的文檔記錄,並且他完全解釋了你的問題。

我也有我的項目,這是一個tab-ish的東西,當你轉到另一個頁面時在頁面之間進行動畫處理。它在vb.net中,沒有很好的文檔,但你可能想看一看。

Here's the projecthere's a image of the designeranimated gif of the end result

編輯:

在我的項目,在 「DesignerControl.vb」 文件,在線187:

' The controldesigner don't always save properties which are changed directly :/ 
Private Sub SetValue(itm As Item, pName$, val As Object) 
    Dim Prop As PropertyDescriptor = TypeDescriptor.GetProperties(itm.Page)(pName) 
    If Prop IsNot Nothing AndAlso Prop.PropertyType Is val.GetType Then Prop.SetValue(itm.Page, val) 
End Sub