【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); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!