簡體   English   中英

將控件添加到設計器中用戶控件上的面板上

[英]Adding controls to a panel on a User Control in designer

我有創建具有特定常用功能的用戶控件的特定要求。 對於該控件,我還要求允許其他開發人員在設計器模式下添加控件以制作特定的UI。 為此,我創建了一個用戶控件,添加了(樣本)標簽和按鈕。 我還添加了一個面板,以允許在控件的特定區域中添加其他控件。

然后,通過添加[Designer]標記和[ControlDesigner],使該類在設計器模式下可見。 這樣可以達到添加具有某些固定內容的User控件並向頁面添加更多控件的預期效果。 問題在於用戶可以在設計模式下移動面板,VisualStudio感到困惑,創建了循環引用。 即使我需要啟用設計模式,也可以關閉面板的調整大小/位置嗎?

注意:我也嘗試只在設計模式下使用用戶控件,但是添加的控件一直消失在用戶控件上的固定控件后面。

下面是代碼和示例。歡迎任何建議/修復。

上面是面板上用戶控件的外觀

在此處輸入圖片說明

上面是一個包含User控件的窗體,並向面板添加了自定義按鈕。.請注意,啟用了面板拖動,如果觸摸,則會在form.designer.cs文件中創建一個循環引用,並且該項目變得不穩定。

最后是用戶控件的類

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

using System.Windows.Forms.Design;

namespace wfcLib
{

    [DesignerAttribute(typeof(MyControlDesigner))]
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
    public partial class ucInput : UserControl
    {

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Panel InternalPanel
        {
            get { return pnlContent; }
            set { pnlContent = value; }
        }
        public ucInput()
        {
            InitializeComponent();

        }

    }
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class MyControlDesigner : System.Windows.Forms.Design.ControlDesigner
    {
        public override void Initialize(IComponent c)
        {
            base.Initialize(c);
            ucInput ctl = (ucInput)c;
            EnableDesignMode(ctl.InternalPanel, "InternalPanel");
        }
    }
}

除了關於將派生Panel與自己的設計器一起使用來覆蓋SelectionRules屬性的評論之外,另一種方法是利用設計器的ISelectionService來檢測所選組件中的更改,如果選擇了面板,則將其移除。

這是通過重寫控件的Site屬性來設置掛鈎來實現的。 還要注意,我將InternalPanel屬性更改為只讀,因為您確實不希望其可寫。

[DesignerAttribute(typeof(MyControlDesigner))]
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class ucInput : UserControl
{

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Panel InternalPanel
    {
        get { return pnlContent; }
    }

    public ucInput()
    {
        InitializeComponent();
    }

    private ISelectionService selectionService;
    private IDesignerHost host;
    public override ISite Site
    {
        get
        {
            return base.Site;
        }
        set
        {
            host = null;
            UnSubscribeFromSelectionService();
            base.Site = value;
            if (value != null)
            {
                host = (IDesignerHost)this.Site.GetService(typeof(IDesignerHost));
                if (host != null)
                {
                    if (host.Loading)
                    {
                        // defer subscription to selection service until fully loaded
                        host.Activated += Host_Activated;
                    }
                    else
                    {
                        SubscribeToSelectionService();
                    }
                }
            }
        }
    }

    private void Host_Activated(object sender, EventArgs e)
    {
        host.Activated -= Host_Activated;
        SubscribeToSelectionService();
    }

    private void SubscribeToSelectionService()
    {
        selectionService = (ISelectionService)this.Site.GetService(typeof(ISelectionService));
        if (selectionService != null)
        {
            selectionService.SelectionChanging += OnSelectionChanging;
        }
    }

    private void UnSubscribeFromSelectionService()
    {
        if (selectionService != null)
        {
            selectionService.SelectionChanging -= OnSelectionChanging;
        }
    }

    private void OnSelectionChanging(object sender, EventArgs e)
    {
        if (selectionService.GetComponentSelected(pnlContent))
        {
            selectionService.SelectionChanging -= OnSelectionChanging;
            selectionService.SetSelectedComponents(new[] { pnlContent }, SelectionTypes.Remove);
            selectionService.SelectionChanging += OnSelectionChanging;
        }
    }
}

編輯:忽略了SelectionService的原始代碼在IDesignerHost加載時不可用。 添加了代碼以推遲訂閱,直到激活IDesignerHost

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM