通过foreach动态添加tabpages,在动态tabpages上添加用户控件

时间: 2023-11-30 14:03:14 浏览: 46
可以按照以下步骤实现: 1. 创建TabControl控件:在窗体上拖拽一个TabControl控件。 2. 动态添加TabPage:使用foreach循环创建多个TabPage,然后将它们添加到TabControl控件中。示例代码如下: ```csharp foreach (var item in items) { var tabPage = new TabPage(item.Name); tabControl1.TabPages.Add(tabPage); } ``` 3. 创建用户控件:在项目中添加一个用户控件(UserControl),然后在用户控件上添加所需的控件。 4. 在动态创建的TabPage上添加用户控件:使用foreach循环遍历TabControl控件中的所有TabPage,然后在每个TabPage上添加一个用户控件。示例代码如下: ```csharp foreach (TabPage tabPage in tabControl1.TabPages) { var userControl = new MyUserControl(); tabPage.Controls.Add(userControl); } ``` 其中,`MyUserControl`是你在第3步中创建的用户控件类名。 这样就可以通过foreach动态添加TabPages,并在每个TabPage上添加一个用户控件了。
相关问题

C#winfrom 新建winfrom From1窗体,在窗体中添加splitContainer1控件控件上左边制作一个包含父级菜单名称和子级功能选项的功能选项栏,并在顶部增加一个功能搜索栏根据输入的子级功能名称高亮显示出来对应的子级功能,在右边添加 tabControl控件,双击子级调用对应的其他窗体填充到tabControl里的TabPages界面(同时显示出子级功能名称)TabPages根据打开的子级功能自动新增一个将子级调用的其他from窗体填充到里面,同时TabPages名称右边包含关闭(X)功能,点击之后关闭调用的from窗体 实现代码

以下是一个简单的实现过程,仅供参考: 1. 添加控件 首先在Form1窗体中添加SplitContainer控件和TabControl控件,以及一个TextBox控件和一个Button控件作为功能搜索栏。在SplitContainer控件的左侧添加Panel控件,用于实现功能选项栏。 2. 实现功能选项栏 在Panel控件中添加Label控件作为父级菜单名称,以及Button控件作为子级功能选项。在Button控件的Click事件中,双击调用对应的其他窗体,将其填充到TabControl控件的TabPages中,并显示出子级功能名称。 3. 实现功能搜索栏 在TextBox控件的TextChanged事件中,根据输入的子级功能名称高亮显示出对应的子级功能。 4. 实现TabPages功能 在TabControl控件的SelectedIndexChanged事件中,根据选择的TabPages名称,自动新增一个将子级调用的其他Form窗体填充到里面,并在TabPages名称右侧包含关闭(X)功能,点击之后关闭调用的Form窗体。 以下是代码实现: ```csharp public partial class Form1 : Form { private List<Button> buttons = new List<Button>(); // 保存所有子级功能选项按钮的列表 private List<Form> forms = new List<Form>(); // 保存所有打开的Form窗体的列表 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // 添加父级菜单名称 Label label = new Label(); label.Text = "父级菜单名称"; label.Dock = DockStyle.Top; panel1.Controls.Add(label); // 添加子级功能选项按钮 for (int i = 0; i < 10; i++) { Button button = new Button(); button.Text = "子级功能" + (i + 1); button.Dock = DockStyle.Top; button.Click += Button_Click; panel1.Controls.Add(button); buttons.Add(button); } } private void Button_Click(object sender, EventArgs e) { // 双击调用对应的Form窗体,并将其填充到TabControl控件的TabPages中 Button button = sender as Button; Form form = new Form(); form.Text = button.Text; form.TopLevel = false; form.FormBorderStyle = FormBorderStyle.None; form.Dock = DockStyle.Fill; tabControl1.TabPages.Add(button.Text); tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(form); form.Show(); forms.Add(form); } private void textBox1_TextChanged(object sender, EventArgs e) { // 根据输入的子级功能名称高亮显示出对应的子级功能 foreach (Button button in buttons) { if (button.Text.Contains(textBox1.Text)) { button.BackColor = Color.Yellow; } else { button.BackColor = Color.White; } } } private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { // 根据选择的TabPages名称,自动新增一个将子级调用的Form窗体填充到里面,并在TabPages名称右侧包含关闭(X)功能,点击之后关闭调用的Form窗体 string tabPageName = tabControl1.SelectedTab.Text; bool formExist = false; foreach (Form form in forms) { if (form.Text == tabPageName) { formExist = true; break; } } if (!formExist) { Form form = new Form(); form.Text = tabPageName; form.TopLevel = false; form.FormBorderStyle = FormBorderStyle.None; form.Dock = DockStyle.Fill; tabControl1.TabPages[tabControl1.SelectedIndex].Controls.Add(form); form.Show(); forms.Add(form); // 在TabPages名称右侧包含关闭(X)功能,点击之后关闭调用的Form窗体 Label label = new Label(); label.Text = " X"; label.Font = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(0))); label.ForeColor = Color.Red; label.Cursor = Cursors.Hand; label.Click += Label_Click; tabControl1.TabPages[tabControl1.SelectedIndex].Controls.Add(label); label.Dock = DockStyle.Right; } } private void Label_Click(object sender, EventArgs e) { // 关闭调用的Form窗体 Label label = sender as Label; TabPage tabPage = label.Parent as TabPage; foreach (Form form in forms) { if (form.Text == tabPage.Text) { form.Close(); forms.Remove(form); break; } } tabControl1.TabPages.Remove(tabPage); } } ```

winform TabControl添加删除键

在 WinForm TabControl 中添加删除键可以让用户更方便地关闭 TabPage,以下是实现步骤: 1. 在 TabControl 控件上添加一个 ContextMenuStrip 上下文菜单,菜单项为“关闭当前选项卡”。 2. 在 TabControl 的 MouseClick 事件中判断是否右键单击,如果是,则弹出上下文菜单。 3. 在上下文菜单的 Click 事件中关闭当前选项卡。 4. (可选)在 TabControl 控件上添加一个 Button 控件,点击该按钮时关闭当前选项卡。 示例代码如下: ```csharp public partial class CustomTabControl : TabControl { private ContextMenuStrip _contextMenuStrip; private Button _closeButton; public CustomTabControl() { InitializeComponent(); InitContextMenu(); InitCloseButton(); } private void InitContextMenu() { _contextMenuStrip = new ContextMenuStrip(); var closeMenuItem = new ToolStripMenuItem("关闭当前选项卡"); closeMenuItem.Click += CloseMenuItem_Click; _contextMenuStrip.Items.Add(closeMenuItem); } private void InitCloseButton() { _closeButton = new Button { Width = 20, Height = 20, FlatStyle = FlatStyle.Flat, ForeColor = Color.Gray, Font = new Font("Marlett", 8.25f), Text = "r", Visible = false }; _closeButton.Click += CloseButton_Click; Controls.Add(_closeButton); } protected override void OnControlAdded(ControlEventArgs e) { base.OnControlAdded(e); e.Control.MouseEnter += Control_MouseEnter; e.Control.MouseLeave += Control_MouseLeave; e.Control.MouseDown += Control_MouseDown; } protected override void OnControlRemoved(ControlEventArgs e) { base.OnControlRemoved(e); e.Control.MouseEnter -= Control_MouseEnter; e.Control.MouseLeave -= Control_MouseLeave; e.Control.MouseDown -= Control_MouseDown; } private void Control_MouseEnter(object sender, EventArgs e) { _closeButton.Visible = true; _closeButton.Top = 2; _closeButton.Left = GetCloseButtonLeft((TabPage)sender) - _closeButton.Width; } private void Control_MouseLeave(object sender, EventArgs e) { _closeButton.Visible = false; } private void Control_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { SelectedTab = (TabPage)sender; } else if (e.Button == MouseButtons.Right) { SelectedTab = (TabPage)sender; _contextMenuStrip.Show(this, e.Location); } } private void CloseMenuItem_Click(object sender, EventArgs e) { if (SelectedTab != null) { TabPages.Remove(SelectedTab); } } private void CloseButton_Click(object sender, EventArgs e) { var closeButton = (Button)sender; var tabPage = (TabPage)closeButton.Tag; TabPages.Remove(tabPage); } private int GetCloseButtonLeft(TabPage tabPage) { var closeButtonWidth = _closeButton.Width; var closeButtonPadding = 2; var tabRect = GetTabRect(TabPages.IndexOf(tabPage)); return tabRect.Right - closeButtonPadding - closeButtonWidth; } protected override void OnResize(EventArgs e) { base.OnResize(e); foreach (TabPage tabPage in TabPages) { var closeButtonLeft = GetCloseButtonLeft(tabPage); tabPage.Controls[0].Left = closeButtonLeft; } } } ``` 在该自定义控件中,我们添加了一个 Button 控件作为关闭按钮,当用户鼠标移入 TabPage 区域时,该按钮才会显示。同时,我们还添加了一个上下文菜单,用户右键单击 TabPage 时,可以选择关闭当前选项卡。

相关推荐

private void btnFromAdd_Click(object sender, EventArgs e) { if (String.IsNullOrEmpty(cmbJobType.Text)) { ExceptionMsgBox.This.ShowMessageBox(MessageType.Warning, "Select JobType", this.Text); return; } //if (String.IsNullOrEmpty(cmbFromPort.Text) || String.IsNullOrEmpty(cmbFromCST.Text)) if (String.IsNullOrEmpty(cmbFromPort.Text)) { ExceptionMsgBox.This.ShowMessageBox(MessageType.Warning, "Select Port", this.Text); return; } if( String.IsNullOrEmpty(txtFromCST.Text)) { ExceptionMsgBox.This.ShowMessageBox(MessageType.Warning, "Check Carrier", this.Text); return; } if (this.duplicateCheckCST(txtFromCST.Text)) { return; } //Split or Scrap or SlotChange ,only select one CST if ( (string.Equals(cmbJobType.Text,SortJobType.Split) || string.Equals(cmbJobType.Text,SortJobType.Scrap)|| string.Equals(cmbJobType.Text,SortJobType.SlotChange)) && tabControl1.TabCount >= 1) { ExceptionMsgBox.This.ShowMessageBox(MessageType.Warning, "SortJobType is " + cmbJobType.Text + ", Source CST only choice One!", this.Text); return; } //string grdtitle = "grdFrom" + cmbFromCST.Text; string grdtitle = "grdFrom" + txtFromCST.Text; TabPage tab = new TabPage(); //tab.Text = this.cmbFromPort.Text + "_" + this.cmbFromCST.Text; tab.Text = cmbFromPort.Text; //tab.Name = "tp" + cmbFromCST.Text; tab.Name = "tp" + txtFromCST.Text; //this.createDesignInstance(tab, grdtitle, cmbFromCST.Text); this.createDesignInstance(tab, grdtitle, txtFromCST.Text); this.tabControl1.TabPages.Add(tab); try { UGrid grdFrom = new UGrid(); Control[] ctrl = this.tabControl1.TabPages[tabControl1.TabCount - 1].Controls.Find(grdtitle, true); if (ctrl.Length > 0) { grdFrom = ctrl[0] as UGrid; } this.tabControl1.SelectTab(tabControl1.TabCount - 1); // zendao 490 setDummyGlassRowHighLight 20210830 foreach (TabPage page in tabControl1.TabPages) { foreach (Control tabPanel in page.Controls) { foreach (Control grid in tabPanel.Controls) { if (grid is UGrid) { UGrid grdProductList = new UGrid(); grdProductList = (UGrid)grid; setDummyGlassRowHighLight(grdProductList); setEmptyGlassActivation(grdProductList); grdProductList.SetPerformAutoResize(); } } } } } catch (Exception err) { UILogger.This.Trace(err); } }

zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

最新推荐

recommend-type

基于springboot+vue+MySQL实现的在线考试系统+源代码+文档

web期末作业设计网页 基于springboot+vue+MySQL实现的在线考试系统+源代码+文档
recommend-type

318_面向物联网机器视觉的目标跟踪方法设计与实现的详细信息-源码.zip

提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
recommend-type

FPGA Verilog 计算信号频率,基础时钟100Mhz,通过锁相环ip核生成200Mhz检测时钟,误差在10ns

结合等精度测量原理和原理示意图可得:被测时钟信号的时钟频率fx的相对误差与被测时钟信号无关;增大“软件闸门”的有效范围或者提高“标准时钟信号”的时钟频率fs,可以减小误差,提高测量精度。 实际闸门下被测时钟信号周期数为X,设被测信号时钟周期为Tfx,它的时钟频率fx = 1/Tfx,由此可得等式:X * Tfx = X / fx = Tx(实际闸门)。 其次,将两等式结合得到只包含各自时钟周期计数和时钟频率的等式:X / fx = Y / fs = Tx(实际闸门),等式变换,得到被测时钟信号时钟频率计算公式:fx = X * fs / Y。 最后,将已知量标准时钟信号时钟频率fs和测量量X、Y带入计算公式,得到被测时钟信号时钟频率fx。
recommend-type

校园二手商品交易系统三.wmv

校园二手商品交易系统三.wmv
recommend-type

基于Spring Security的OAuth2.1和OIDC1.0认证服务器设计源码

本源码提供了一个基于Spring Security框架的OAuth2.1和OIDC1.0认证服务器实现。项目包含102个文件,主要使用Java(51个文件)、JSP(12个文件)、XML(10个文件)、HTML(9个文件)等编程语言和标记语言开发。此外,还包括了properties、txt、ddl、css、ico等格式的文件。这个认证服务器项目旨在实现现代的身份验证和授权机制,支持OAuth 2.1和OpenID Connect 1.0协议,适用于需要在应用程序中实现安全认证的开发者。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

hive中 的Metastore

Hive中的Metastore是一个关键的组件,它用于存储和管理Hive中的元数据。这些元数据包括表名、列名、表的数据类型、分区信息、表的存储位置等信息。Hive的查询和分析都需要Metastore来管理和访问这些元数据。 Metastore可以使用不同的后端存储来存储元数据,例如MySQL、PostgreSQL、Oracle等关系型数据库,或者Hadoop分布式文件系统中的HDFS。Metastore还提供了API,使得开发人员可以通过编程方式访问元数据。 Metastore的另一个重要功能是跟踪表的版本和历史。当用户对表进行更改时,Metastore会记录这些更改,并且可以让用户回滚到
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。