[英]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.