【WinForm】DEV DockManager、DockPanel使用汇总

一、DockManager

1、清除DockManager里的所有Panel

调用dockManager1.Clear()后,再读dockManager1.Panels.Count发现数量不变,只能用RemovePanel()方法来实现:

            int cnt = dockManager1.Panels.Count;
            for (int p = cnt - 1; p >= 0; p--)
            {
                dockManager1.RemovePanel(dockManager1.Panels[p]);
            }

 

2、动态添加DockPanel界面闪烁

尝试了两种方法:

(1)先不显示DockPanel,加载完毕后再显示

试了用dockManager1.AddPanel(DockingStyle.Left, panel)添加Panel时,配置panel.Visibility = DockVisibility.Hide。后面再设置Panel可见,但

            for (int p = 0; p < dockManager1.Panels.Count; p++)
            {
                dockManager1.Panels[p].Visibility = DockVisibility.Visible;
            }

不生效,DockPanel没有显示出来。用Show()方法和Hide()方法也是一样。不知道为啥。

 

(2)在动态添加DockPanel前调用dockManager1.BeginInit(),添加完毕后调用dockManager1.EndInit()。可优化闪烁问题。

 

3、多个DockPanel以Tab标签形式显示时,怎么取消点击右键出现的菜单

在主界面添加了一个DocumentManager和一个DockManager,添加的DockPanel都设置DockedAsTabbedDocument属性为true(填满界面),有如下情况:

(1)在标签上右键会显示菜单

(2)在标签右侧空白处点击右键也会有个“Windows..”菜单

解决方法:没有在属性中找到相应方案,确认当前界面没有其他控件需要右键菜单后,直接屏蔽整个界面的右键事件:

窗口继承IMessageFilter接口:

public partial class MainForm : RibbonForm,IMessageFilter
{
    ...
}

在界面初始化时添加:

Application.AddMessageFilter(this);

添加函数:

        public bool PreFilterMessage(ref System.Windows.Forms.Message MyMessage)
        {
            //不响应鼠标右键消息
            if (MyMessage.Msg >= 516 && MyMessage.Msg <= 517)
            {
                return true;
            }
            return false;
        }

参考:https://www.cnblogs.com/yunzhongchen/p/6246431.html

 

4、拖拽DockPanel浮动后无法拖拽停靠到回原位置

问题描述:添加的DockPanel都设置DockedAsTabbedDocument属性为true,以tab标签形式显示。每个DockPanel动态添加一个UserControl,拖拽DockPanel浮动后无法拖拽停靠到回原位置(点击时焦点没有回到该DockPanel控件上,类似失能了)。不添加UserControl时可以拖拽。

问题所在:动态添加UserControl时直接添加到了DockPanel的控件列表里。

dockManager1.RootPanels[p].Controls.Add(uc1);

解决方案:必须在DockPanel的子容器ControlContainer里添加UserControl才能正常实现拖拽停靠。

dockManager1.RootPanels[p].Controls[0].Controls.Add(uc1);

二、DockPanel

1、不显示DockPanel右上方最大化、隐藏、关闭按钮

 

2、动态向DockManager中增加DockPanel,并向DockPanel中动态加入用户控件

        DockPanel rootPanel;
        private void CreatDockPanel()
        {
            for (int i = 0; i < 2; i++)
            {
                if (rootPanel == null)
                {
                    rootPanel = new DockPanel();
                    var dockpanel_container = new ControlContainer();//创建一个容器对象

                    //此项必须,如果不将容器对象加入到panel中,则会出现子窗体Form将Panel覆盖的情况
                    //此现象会造成将panel拖出窗体浮动时,就无法再进行拖动,只需要给最顶层的panel加这个对象就行了
                    rootPanel.Controls.Add(dockpanel_container);
                    rootPanel.Name = string.Format("dk_{0}", i + 1);
                    rootPanel.Text = string.Format("Panel{0}", i + 1); ;
                    userControl form2 = new userControl(i);
                    form2.Dock = DockStyle.Fill;
                    rootPanel.Controls.Add(form2);
                    form2.Visible = true;

                    //注意,如果主窗体上没有加入 documentManager,则panel无法Fill
                    this.dockManager1.AddPanel(DockingStyle.Left, rootPanel);

                    ////加入 documentManager 之后,只用设置此属性则此panel直接就在中间占满
                    rootPanel.DockedAsTabbedDocument = true;
                }
                else
                {
                    //加入其它窗体,因为panel2是由其它的panel创建的,所以不再需要加入容器 ControlContainer
                    DockPanel panel2 = rootPanel.AddPanel();
                    panel2.Name = string.Format("dk_{0}", i + 1);
                    panel2.Text = string.Format("Panel{0}", i + 1); ;
                    userControl form3 = new userControl(i);
                    form3.Dock = DockStyle.Fill;
                    panel2.Controls.Add(form3);
                    form3.Visible = true;
                }
            }
        }

这个方法可以让DockPanel以Fill的方式填充界面,且多个DockPanel时为Tab样式。

参考:https://www.cnblogs.com/rbzz/articles/13615108.html

 

若不想Fill,则使用下面的方法(只能停靠,DockingStyle设为Fill时AddPanel返回NULL)

        /// <summary>
        /// 动态加载dockpanel
        /// </summary>
        private void CreatDockPanel()
        {
            DockPanel runPanel = dockManager1.AddPanel(DockingStyle.Left);
            runPanel.Name = "Dock1";
            runPanel.Text = "信息";
            //runPanel.Height = 500;
            runPanel.Width = 500;

            DockPanel samePanel = null;
            //查找相同位置是否已有停靠插件
            foreach (DockPanel hasPanel in dockManager1.Panels)
            {
                if (hasPanel.Name != "Dock1" && hasPanel.Dock == DockingStyle.Left)
                {
                    samePanel = hasPanel;
                    break;
                }
            }

            if (samePanel != null)
            {
                runPanel.DockAsTab(samePanel);
            }

            runPanel.Show();
            //DockPanel有两种停靠模式,Split和Tab模式
            //Split模式界面:两个DockPanel根据实际停靠风格并立在一起。
            //Tab模式:两个DockPanel是以分页样式融合在一起
            //默认情况下,当我们建立好两个DockPanel,将它们直接show出来,它们呈现的就是Split模式


            ////Tab模式
            ////创建一个左停靠控件  
            //DockPanel panel1 = dockManager1.AddPanel(DockingStyle.Left);  
            //panel1.Text = "runDockPanel1"; 
            ////由panel1添加一个停靠控件
            ////如果直接把panel1和panel2都show出来,我们可以看到它们是Split模式  
            //DockPanel panel2 = panel1.AddPanel();  
            //panel2.Text = " runDockPanel2";  
            ////将二者的共同父容器设置为Tab模式  
            //DockPanel container = panel1.ParentPanel;  
            //container.Tabbed = true;  

            //当某个位置(如左边)只有一个DockPanel时,该DockPanel的ParentPanel和RootPanel都是自己。当存在两个及以上DockPanel时,所有DockPanel的ParentPanel和RootPanel都是由系统生成的一个公共DockPanelContainer作为父容器,该容器容纳所有同位置的DockPanel。
            //UserControl1 UserControl11 = new UserControl1();
            //AddControlToPanel(runPanel, UserControl11);
        }

 

posted @ 2022-07-06 10:48  不溯流光  阅读(1701)  评论(0编辑  收藏  举报