将控件添加到设计器中用户控件上的面板

罗伯特·弗莱明

我有一个特定的要求来创建具有特定常用功能的用户控件。对于该控件,我还要求允许其他开发人员在设计器模式下添加控件以制作特定的 UI。为此,我创建了一个用户控件,添加(示例)标签和按钮。我还添加了一个面板,允许在控件的特定区域添加附加控件。

然后,我通过添加 [Designer] 标记和 [ControlDesigner] 使该类在设计器模式下可见。这给出了添加具有一些固定内容的用户控件以及向页面添加更多控件的预期效果。问题是用户可以在设计模式下移动面板,而 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");
        }
    }
}
锰锡

除了我关于使用具有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;
        }
    }
}

编辑:原始代码忽略SelectionServiceIDesignerHost在加载时不可用的原因。添加了将订阅推迟到IDesignerHost激活的代码

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将控件添加到用户控件

在运行时将控件添加到用户控件的内部面板

视觉继承-将设计器中的控件添加到TableLayoutPanel中托管的面板

将控件添加到窗口时,用户控件上的按钮大小会发生变化

以编程方式将项目添加到用户控件

将排序添加到具有多个Expander控件的用户控件中

将键盘控件添加到滑块

将控件添加到Jquery Carousel

将控件添加到新类

将字母控件添加到输入

将属性添加到控件类

将控件添加到Contextmenu

将控件添加到面板时,C# 索引不可预测

将面板控件动态添加到动态标签页 (C++ Builder Rad Studio)?

顶级控件不能添加到控件

将 ErrorTemplate 添加到 WPF 用户控件会禁用文本框输入

将PreRender事件添加到asp.net中的用户控件

在Designer支持下将表单作为属性添加到用户控件

将“隐藏字段”控件切换添加到“ ACF字段”,以方便用户隐藏

将listview控件添加到用户窗体时出现错误800a9cf1

将列添加到属于自定义用户控件的DataGridView中

动态地将用户控件添加到FlowLayoutPanel

如何在 WPF 中动态地将准备好的控件添加到包装面板?

将分页控件添加到整页触摸滑动器/滑块-Hammer.js

以编程方式将控件添加到转发器项目模板

Excel VBA将滚动器添加到窗体控件组合框

是否可以将<SearchBar>控件添加到<ToolbarItem>?

如何将工具提示添加到控件?

将PictureBox数组添加到控件中