用DesignSurface对象实现设计的两个问题. DesignSurface surface = new DesignSurface();
 surface.BeginLoad(typeof(System.Windows.Forms.Form));            Control view = (Control)surface.View;
            view.Dock = DockStyle.Fill;
            view.Parent = this.PelMain;
第一个是如何在宿主(view)中实现快捷菜单:如锁定、复制、删除、移到上层等。IDesignerHost idh = (IDesignerHost)surface.GetService(typeof(IDesignerHost));
IComponentChangeService icc = (IComponentChangeService)idh.GetService(typeof(IComponentChangeService));icc.ComponentRemoved += new ComponentEventHandler(icc_ComponentRemoved); 
第二个:虽然可通过这个事件知道要移除的控件,但有些控件不让移除如何做。谢谢!

解决方案 »

  1.   

    这是个非常简单的例子,演示了用ISelectionService来获得当前组件,并用PropertyGrid来编辑该组件。
    也演示了锁定、复制、删除、移到上层等简单操作,以及在锁定的状态下禁止一些操作。虽然例子本身非常简单,但设计器本身是个非常大的议题,因此代码将分两部分贴出。
    有兴趣的朋友们还可以参考:Windows Forms Programming: Design-Time Architecture
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    using System.ComponentModel.Design;
    using System.ComponentModel.Design.Serialization;namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            DesignSurface designSurface;
            IDesignerHost formDesignerHost;        public Form1()
            {
                InitializeComponent();
                InitializeDesignerSurface();
                InitializeListBox();            this.propertyGrid1.SelectedObject = this.formDesignerHost.RootComponent;
            }        private void InitializeDesignerSurface()
            {
                this.designSurface = new System.ComponentModel.Design.DesignSurface(typeof(Form));
                Control view =  this.designSurface.View as Control;
                this.tableLayoutPanel1.Controls.Add(view, 0, 0);
                this.tableLayoutPanel1.SetRowSpan(view, 2);
                view.Dock = DockStyle.Fill;            this.formDesignerHost = this.designSurface.GetService(typeof(IDesignerHost)) as IDesignerHost;
                this.formDesignerHost.AddService(typeof(INameCreationService), new MyNameService());
                ISelectionService selectionService = this.formDesignerHost.GetService(typeof(ISelectionService)) as ISelectionService;
                
                selectionService.SelectionChanged += delegate
                {
                    System.Collections.ICollection collection = selectionService.GetSelectedComponents();
                    object[] selectedObjects = new object[collection.Count];
                    collection.CopyTo(selectedObjects, 0);
                    this.propertyGrid1.SelectedObjects = selectedObjects;
                };
            }        private void InitializeListBox()
            {
                this.listBox1.DisplayMember = "Name";
                this.listBox1.DataSource = new Type[]
                {
                    typeof(Label), typeof(Button), typeof(TextBox), typeof(RadioButton),typeof(CheckBox),
                };            this.listBox1.DoubleClick += delegate
                {
                    CreateControl(this.listBox1.SelectedItem as Type);
                };
            }        private void CreateControl(Type controlType)
            {
                if (typeof(Control).IsAssignableFrom(controlType) && !typeof(Form).IsAssignableFrom(controlType))
                {
                    Control control = this.formDesignerHost.CreateComponent(controlType) as Control;
                    control.Text = control.Name;
                    control.Location = new Point(5, System.Environment.TickCount % 200);
                    (this.formDesignerHost.RootComponent as Form).Controls.Add(control);
                }
            }        private void btnLock_Click(object sender, EventArgs e)
            {
                foreach (IComponent component in this.propertyGrid1.SelectedObjects)
                {
                    PropertyDescriptor lockedProperty = TypeDescriptor.GetProperties(component)["Locked"];
                    if (lockedProperty != null)
                    {
                        lockedProperty.SetValue(component, true);
                        this.propertyGrid1.Refresh();
                    }
                }
            }        private void btnCopy_Click(object sender, EventArgs e)
            {
                Control control = this.propertyGrid1.SelectedObject as Control;
                if (control != null) CreateControl(control.GetType());
            }        private void btnDelete_Click(object sender, EventArgs e)
            {
                foreach (IComponent component in this.propertyGrid1.SelectedObjects)
                {
                    if (component is Form == false && !IsLocked(component))
                    {
                        this.formDesignerHost.DestroyComponent(component);
                    }
                }        }        private void btnBringforward_Click(object sender, EventArgs e)
            {
                Control control = this.propertyGrid1.SelectedObject as Control;
                if (control != null && !IsLocked(control) ) control.BringToFront();
            }        private bool IsLocked(IComponent component)
            {
                PropertyDescriptor lockedProperty = TypeDescriptor.GetProperties(component)["Locked"];
                if (lockedProperty != null) return (bool)lockedProperty.GetValue(component);
                return false;
            }    }    class MyNameService : INameCreationService
        {
            static int s_i = 0;
            public string CreateName(IContainer container, Type dataType)
            {
                return dataType.Name + s_i++;
            }        public bool IsValidName(string name)
            {
                if (string.IsNullOrEmpty(name) == true) return false;
                if (char.IsDigit(name[0])) return false;
                foreach(char ch in name)
                {
                    if (char.IsLetterOrDigit(ch) == false && ch != '_') return false;
                }
                return true;
            }        public void ValidateName(string name)
            {
                if (!IsValidName(name)) throw new Exception("Invalid name");
            }
        }
    }
      

  2.   


    // Form1.Designer.cs
    namespace WindowsFormsApplication1
    {
        partial class Form1
        {
            private System.ComponentModel.IContainer components = null;        protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }        #region Windows Form Designer generated code
            private void InitializeComponent()
            {
                this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
                this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
                this.groupBox1 = new System.Windows.Forms.GroupBox();
                this.btnBringforward = new System.Windows.Forms.Button();
                this.btnDelete = new System.Windows.Forms.Button();
                this.btnCopy = new System.Windows.Forms.Button();
                this.btnLock = new System.Windows.Forms.Button();
                this.listBox1 = new System.Windows.Forms.ListBox();
                this.tableLayoutPanel1.SuspendLayout();
                this.groupBox1.SuspendLayout();
                this.SuspendLayout();
                // 
                // tableLayoutPanel1
                // 
                this.tableLayoutPanel1.ColumnCount = 2;
                this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
                this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 300F));
                this.tableLayoutPanel1.Controls.Add(this.propertyGrid1, 1, 0);
                this.tableLayoutPanel1.Controls.Add(this.groupBox1, 1, 1);
                this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
                this.tableLayoutPanel1.RowCount = 2;
                this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 70F));
                this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 30F));
                // 
                // propertyGrid1
                // 
                this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
                // 
                // groupBox1
                // 
                this.groupBox1.Controls.Add(this.listBox1);
                this.groupBox1.Controls.Add(this.btnBringforward);
                this.groupBox1.Controls.Add(this.btnDelete);
                this.groupBox1.Controls.Add(this.btnCopy);
                this.groupBox1.Controls.Add(this.btnLock);
                this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
                this.groupBox1.TabStop = false;
                this.groupBox1.Text = "Double click the listbox to add control";
                // 
                // btnBringforward
                // 
                this.btnBringforward.Location = new System.Drawing.Point(6, 138);
                this.btnBringforward.Size = new System.Drawing.Size(136, 35);
                this.btnBringforward.TabIndex = 1;
                this.btnBringforward.Text = "&Bring Forward";
                this.btnBringforward.Click += new System.EventHandler(this.btnBringforward_Click);
                // 
                // btnDelete
                // 
                this.btnDelete.Location = new System.Drawing.Point(6, 100);
                this.btnDelete.Size = new System.Drawing.Size(136, 35);
                this.btnDelete.TabIndex = 2;
                this.btnDelete.Text = "&Delete";
                this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
                // 
                // btnCopy
                // 
                this.btnCopy.Location = new System.Drawing.Point(7, 62);
                this.btnCopy.Size = new System.Drawing.Size(135, 35);
                this.btnCopy.TabIndex = 3;
                this.btnCopy.Text = "&Copy";
                this.btnCopy.Click += new System.EventHandler(this.btnCopy_Click);
                // 
                // btnLock
                // 
                this.btnLock.Location = new System.Drawing.Point(7, 21);
                this.btnLock.Size = new System.Drawing.Size(135, 35);
                this.btnLock.TabIndex = 4;
                this.btnLock.Text = "&Lock";
                this.btnLock.Click += new System.EventHandler(this.btnLock_Click);
                // 
                // listBox1
                // 
                this.listBox1.FormattingEnabled = true;
                this.listBox1.ItemHeight = 16;
                this.listBox1.Location = new System.Drawing.Point(149, 22);
                this.listBox1.Size = new System.Drawing.Size(139, 148);
                this.listBox1.TabIndex = 2;
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(963, 616);
                this.Controls.Add(this.tableLayoutPanel1);
                this.Name = "Form1";
                this.Text = "Designer Host";
                this.tableLayoutPanel1.ResumeLayout(false);
                this.groupBox1.ResumeLayout(false);
                this.ResumeLayout(false);        }        #endregion        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
            private System.Windows.Forms.PropertyGrid propertyGrid1;
            private System.Windows.Forms.GroupBox groupBox1;
            private System.Windows.Forms.Button btnBringforward;
            private System.Windows.Forms.Button btnDelete;
            private System.Windows.Forms.Button btnCopy;
            private System.Windows.Forms.Button btnLock;
            private System.Windows.Forms.ListBox listBox1;
        }
    }// Program.cs
    using System;
    using System.Windows.Forms;namespace WindowsFormsApplication1
    {
        static class Program
        {
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }