我有创建具有特定常用功能的用户控件的特定要求。对于该控件,我还要求允许其他开发人员在设计器模式下添加控件以制作特定的UI。为此,我创建了一个用户控件,添加了(样本)标签和按钮。我还添加了一个面板,以允许在控件的特定区域中添加其他控件。
然后,通过添加[Designer]标记和[ControlDesigner],使该类在设计器模式下可见。这样可以达到添加具有某些固定内容的User控件并向页面添加更多控件的预期效果。问题在于用户可以在设计模式下移动面板,VisualStudio感到困惑,创建了循环引用。即使我需要启用设计模式,也可以关闭面板的调整大小/位置吗?
注意:我还尝试只在设计模式下使用用户控件,但是添加的控件一直消失在用户控件上的固定控件后面。
代码和示例如下。欢迎任何建议/修复。
上面是面板上用户控件的外观
上面是一个包含用户控件的窗体,并向该面板添加了自定义按钮。.请注意,启用了面板拖动,如果触摸,则会在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");
}
}
}
答案 0 :(得分:0)
除了我的评论有关将派生的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
为止。