WPF动态加载TabControl
主要讲一下如何通过点击菜单,实现动态加载TabControl的功能,准确来说应该是动态加载TabItem,要实现这个功能,我们需要解决两个问题:
- 点击菜单的时候,需要传进来一个你要加载的UserControl控件的名称,让程序知道你要加载的是哪个控件。
- 通过传进来的UserControl控件名实例化UserControl控件(利用反射来实例化UserControl控件)。
关于第一点,我通过在数据库菜单表加一个字段Code,用来保存UserControl控件的名称,然后在加载菜单的时候,给菜单的Name赋上Code的值,关于动态加载菜单可以看我上一篇博客。
在xaml添加一个Name="TabControl"的TabControl
CS后台代码:
我们在添加菜单的时候,根据菜单的Name值是否为空,给菜单添加点击事件
/// <summary>/// 添加菜单的点击事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Item_Click(object sender, RoutedEventArgs e){MenuItem item = sender as MenuItem;bool isExist = false;foreach (TabItem tab in this.TabControl.Items){//如果已经存在这个TabItem,就把焦点设置到这个TabItem上if (tab.Header == item.Header){isExist = true;tab.Focus();}}//如果不存就添加一个TabItemif (!isExist){//获取命名空间名称(这个名称一定要完整)string str = string.Format("WPFTest.{0}", item.Name);UserControl userControl = ReflectionHelper.CreateInstance<UserControl>(str, "WPFTest");//程序集名称TabItem tabItem = new TabItem(){Header = item.Header,Name = item.Name};tabItem.Content = userControl;this.TabControl.Items.Add(tabItem);tabItem.Focus();}}
添加一个反射帮助类ReflectionHelper,在里面添加一个创建对象实例的方法CreateInstance:
/// <summary>/// 创建对象的实例/// </summary>/// <typeparam name="T"></typeparam>/// <param name="fullName">命名空间.类名</param>/// <param name="assemblyName">程序集名称</param>/// <returns></returns>public static T CreateInstance<T>(string fullName, string assemblyName){//命名空间.类名,程序集名称string path = fullName + "," + assemblyName;//获取加载类型Type o = Type.GetType(path);//根据类型创建实例object obj = Activator.CreateInstance(o, true);//类型转换并返回return (T)obj;}
这样我们就可以动态的实例化UserControl控件对象,实现动态加载TabItem的功能了。
为了方便理解,补上完整代码:
public MainWindow(){InitializeComponent();LoadSystemMenu();}/// <summary>/// 加载菜单/// </summary>public void LoadSystemMenu(){//查询出数据库所有的菜单数据DataTable dataTable = model.GetSystemMenu();//筛选出上级ID为空的数据(一级菜单)DataRow[] dataRows = dataTable.Select("SuperiorID is null");//用来存放一级菜单List<MenuItem> menuItems = new List<MenuItem>();foreach (DataRow item in dataRows){MenuItem menu = new MenuItem();menu.Header = item["Name"].ToString();menu.Name = item["Code"].ToString();//UserControl控件名称menu.RenderSize = new Size(100, 25);//如果Code不为空,就添加点击事件if (!string.IsNullOrWhiteSpace(item["Code"].ToString())) menu.Click += Item_Click;//添加子菜单AddChildMenu(menu, item["ID"].ToString(), dataTable);menuItems.Add(menu);}//把一级菜单绑定到菜单栏foreach (MenuItem item in menuItems){this.SystemMenu.Items.Add(item);}}/// <summary>/// 添加子菜单/// </summary>/// <param name="menu"></param>/// <param name="superiorId"></param>/// <param name="dataTable"></param>private void AddChildMenu(MenuItem menu, string superiorId, DataTable dataTable){//筛选出上级菜单ID等于传进来的菜单ID的数据(子菜单)DataRow[] dataRows = dataTable.Select("SuperiorID =" + superiorId);foreach (DataRow item in dataRows){MenuItem menuItem = new MenuItem();menuItem.Header = item["Name"].ToString();menuItem.Name = item["Code"].ToString();//UserControl控件名称menuItem.RenderSize = new Size(100, 25);if (!string.IsNullOrWhiteSpace(item["Code"].ToString())) menuItem.Click += Item_Click;//绑定子菜单menu.Items.Add(menuItem);AddChildMenu(menuItem, item["ID"].ToString(), dataTable);}}/// <summary>/// 添加菜单的点击事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Item_Click(object sender, RoutedEventArgs e){MenuItem item = sender as MenuItem;bool isExist = false;foreach (TabItem tab in this.TabControl.Items){//如果已经存在这个TabItem,就把焦点设置到这个TabItem上if (tab.Header == item.Header){isExist = true;tab.Focus();}}//如果不存就添加一个TabItemif (!isExist){//获取命名空间名称(这个名称一定要完整)string str = string.Format("WPFTest.{0}", item.Name);UserControl userControl = ReflectionHelper.CreateInstance<UserControl>(str, "WPFTest");//程序集名称TabItem tabItem = new TabItem(){Header = item.Header,Name = item.Name};tabItem.Content = userControl;this.TabControl.Items.Add(tabItem);tabItem.Focus();}}
WPF动态加载TabControl相关推荐
- WPF 动态加载DataGrid
自己记录一下怕自己以后都忘记了. 言归正传,所谓动态加载DataGrid就是说表头和数据都是动态生成出来的,不是预先设置好的值. 在网上也找了很久这方面的资料,然后功夫不负有心人还是找到了,然后写一下 ...
- 在WPF中加载gif动态图片
向WPF中加载动态图片有很多种办法,下面介绍一种比较简单的办法. 右键项目,在管理程序包中添加XamlAnimatedGif包,进行安装. . 在设计文件中添加头文件XamlAnimatedGif的头 ...
- XamlReader 动态加载XAML
原文:XamlReader 动态加载XAML XAML: <Grid xmlns:x="http://schemas.microsoft.com/client/2006" x ...
- C#使用IconFont字体图标的动态加载(&#xe格式转换)
IconFont 矢量字体图标由于文件小,资源多,可任意放大缩小不失真,方便着色等特点,在网页.Winform.WPF中被广泛使得.网页上介绍使用的文件很多,但动态加载并不多,本文将重点介绍利用C#语 ...
- js 动态加载select触发事件
动态加载select后,手动调用一下 subjectChange函数,模拟触发change事件 function hallidChange(value) {$.ajax({type: "po ...
- cascader 动态加载 回显_ElementUI cascader级联动态加载回显和搜索看这个就够了
这一篇是上一次讨论cascader级联动态加载回显问题的延续,文末有链接. 以下是思考和开发的过程,不感兴趣可以直接看使用文档. https://github.com/zhuss/lazy-casca ...
- C#动态加载DLL(转)
利用反射进行动态加载和调用. Assembly ass=Assembly.LoadFrom(DllPath); //利用dll的路径加载 加载dll后,需要使用dll中某类. Type type=as ...
- 利用反射实现类的动态加载
为什么80%的码农都做不了架构师?>>> //首先定义一个接口来隔离类: public interface Operator { // public java.util.Lis ...
- 利用 JQuery的load函数动态加载页面
利用JQuery的load函数动态加载页面 JQuery有好多Ajax函数,其中load是用来动态加载一个页面的内容到指定的dom元素上. 我们来做个例子: 做一个上下(左右)结构的页面,其中下左部分 ...
最新文章
- 5亿整数的大文件,怎么排?
- android studio没有org.apache.http.client.HttpClient;等包问题 解决方案
- C++ 术语(C++ Primer)
- numeric column can contains null
- LeetCode(235)——二叉搜索树的最近公共祖先(JavaScript)
- MVC中关于JSON的处理
- 倍福--软件界面介绍
- cad10版计算机快键在哪,CAD快捷键大全在哪里看?CAD快捷键大全与CAD技巧汇总
- java正整数分解因数_java如何将一个正整数分解质因数
- 走向面试之数据库基础:一、你必知必会的SQL语句练习-Part 2
- swagger 怎么去掉get delete_橡皮擦英文单词怎么读
- Swift不深入只浅出入门教程-孟祥月-专题视频课程
- 2012-2013年世界大学计算机专业排名
- Cisco(64)——路由策略综合
- hive的UDF函数的使用。常见UDF函数
- linux 文件操作write详解
- ASP实现自动发邮件
- 笔试题目---描述在浏览器中敲入一个网址并按下回车后所发生的事情
- php足疗预约,足浴养生管理系统轻松实现各种线上预约功能?
- ENVI5.3.1,按经纬度裁剪影像
热门文章
- 【mybatis源码分析(四)】mybatis事务实现原理
- Go 模板库:性能比较
- 2个阶乘什么意思_2的阶乘的阶乘是什么啊?就是2!!代表的什么意思?怎样计算?谢谢...
- 基于DCGAN动漫头像生成的课题意义200字
- 2021-2022-2 ACM集训队每周程序设计竞赛(1) - 问题 E: 祖玛的复仇 - 题解
- 认真CS☀️初始化数组元素、foreach语句
- 计算机辅助数学教学赛课总结,利用信息技术辅助数学教学的体会论文
- 20170518关于zabbix监控路由器交换机
- PoS淘金热潮,全节点对于分布式网络到底意味着什么?
- 关于软件开发,都应该知道的10个常识