【问题标题】:Delete Child Controls from designer code从设计器代码中删除子控件
【发布时间】:2017-07-20 10:28:01
【问题描述】:

我正在使用自定义 TabPages 创建自己的 TabControl。除了删除部分外,它进展顺利。当我将 TabControl 添加到设计器中的表单时,一切正常,添加了 2 个默认 TabPages 并绘制了控件。但是,当我从设计器中的窗体中删除 TabControl 时,属于 TabControl.Controls 集合的 TabPages 不会从设计器代码中删除。他们只是失去了父母。

有什么想法吗?

对于创建,我使用以下代码。

    public class CustomTabControlDesigner : ParentControlDesigner
{
    DesignerVerbCollection _fVerbs;
    public override DesignerVerbCollection Verbs
    {
        get
        {
            if (_fVerbs == null)
            {
                _fVerbs = new DesignerVerbCollection(new[] { new DesignerVerb("Add Tab", OnAdd), new DesignerVerb("Del Tab", OnDel) });
            }

            return _fVerbs;
        }
    }

    void OnAdd(object sender, EventArgs e)
    {
        IDesignerHost designerHost = (IDesignerHost)GetService(typeof(IDesignerHost));
        if (designerHost != null)
        {
            WTabPage newPage = (WTabPage)designerHost.CreateComponent(typeof(WTabPage));
            //newPage.Text = newPage.Name;

            ((WTab)Component).Controls.Add(newPage);
        }
    }
    void OnDel(object sender, EventArgs e)
    {
        IDesignerHost designerHost = (IDesignerHost)GetService(typeof(IDesignerHost));
        if (designerHost != null)
        {
            ((WTab)Component).Controls.Remove(((WTab)Component).SelectedTab);
        }
    }

    public override void InitializeNewComponent(IDictionary defaultValues)
    {
        base.InitializeNewComponent(defaultValues);

        for (int i = 0; i < 2; i++)
        {
            OnAdd(this, EventArgs.Empty);
        }
    }
    //protected override void Dispose(bool disposing)
    //{
    //    for (int i = ((WTab)Component).Controls.Count - 1; i >= 0; i--)
    //    {
    //        ((WTab)Component).Controls.Remove(((WTab)Component).Controls[i]);
    //    }

    //    base.Dispose(disposing);
    //}

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        // Selection of tabs via mouse
        if (m.Msg == 0x201/*WM_LBUTTONDOWN*/)
        {
            WTab control = (WTab)Component;

            int lParam = m.LParam.ToInt32();

            Point hitPoint = new Point(lParam & 0xffff, lParam >> 0x10);

            if (Control.FromHandle(m.HWnd) == null) // Navigation
            {
                if (hitPoint.X < 18 && control.SelectedIndex > 0) // Left
                {
                    control.SelectedIndex--;
                }

                else
                {
                    control.SelectedIndex++; // Right}
                }
            }
            else
            {
                // Header click
                for (int i = 0; i < control.TabCount; i++)
                {
                    if (control.GetTabRect(i).Contains(hitPoint))
                    {
                        control.SelectedIndex = i;

                        return;
                    }
                }
            }
        }
    }
    protected override void OnDragDrop(DragEventArgs de)
    {
        ((IDropTarget)((WTab)Component).SelectedTab).OnDragDrop(de);
    }
    protected override void OnDragEnter(DragEventArgs de)
    {
        ((IDropTarget)((WTab)Component).SelectedTab).OnDragEnter(de);
    }
    protected override void OnDragLeave(EventArgs e)
    {
        ((IDropTarget)((WTab)Component).SelectedTab).OnDragLeave(e);
    }
    protected override void OnDragOver(DragEventArgs de)
    {
        ((IDropTarget)((WTab)Component).SelectedTab).OnDragOver(de);
    }
}

OnAdd 和 OnDel 不是在添加或删除控件时由任务触发的:Task Img

【问题讨论】:

  • 您是否应该将OnDel 中的((WTab)Component).Controls.Remove(((WTab)Component).SelectedTab); 替换为((WTab)Component).Controls.Clear();
  • 按我的理解删除控件时不会触发OnDel方法,它是在TabControl Tasks中按下右上角的三角形时使用的。
  • 你覆盖WTab的Dispose方法吗?您可以发布您的控件代码WTabWTabPage 吗?特别是添加/删除页面的代码以及任何处理方法。

标签: c# tabcontrol designer tabpage


【解决方案1】:

你试过IDesignerHost.DestroyComponent(...)吗?

void OnDel(object sender, EventArgs e)
{
    IDesignerHost designerHost = (IDesignerHost) GetService(typeof(IDesignerHost));
    if (designerHost != null)
    {
        var tab = ((WTab) Component).SelectedTab;
        ((WTab) Component).Controls.Remove(tab);
        designerHost.DestroyComponent(tab);
    }
}

【讨论】:

【解决方案2】:

基于@Pablo notPicasso 他的回答,我使用了以下似乎可行的代码。这有什么不对吗?

        protected override void Dispose(bool disposing)
    {
        IDesignerHost designerHost = (IDesignerHost)GetService(typeof(IDesignerHost));
        if (designerHost != null)
        {
            for (int i = ((WTab)Component).Controls.Count - 1; i >= 0; i--)
            {
                //
                var tab = ((WTab)Component).Controls[i];

                //
                ((WTab)Component).Controls.Remove(tab);

                //
                designerHost.DestroyComponent(tab);
            }
        }

        base.Dispose(disposing);
    }

【讨论】:

    猜你喜欢
    • 2013-08-19
    • 1970-01-01
    • 2012-01-15
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    相关资源
    最近更新 更多