主要讲一下如何通过点击菜单,实现动态加载TabControl的功能,准确来说应该是动态加载TabItem,要实现这个功能,我们需要解决两个问题:

  1. 点击菜单的时候,需要传进来一个你要加载的UserControl控件的名称,让程序知道你要加载的是哪个控件。
  2. 通过传进来的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相关推荐

  1. WPF 动态加载DataGrid

    自己记录一下怕自己以后都忘记了. 言归正传,所谓动态加载DataGrid就是说表头和数据都是动态生成出来的,不是预先设置好的值. 在网上也找了很久这方面的资料,然后功夫不负有心人还是找到了,然后写一下 ...

  2. 在WPF中加载gif动态图片

    向WPF中加载动态图片有很多种办法,下面介绍一种比较简单的办法. 右键项目,在管理程序包中添加XamlAnimatedGif包,进行安装. . 在设计文件中添加头文件XamlAnimatedGif的头 ...

  3. XamlReader 动态加载XAML

    原文:XamlReader 动态加载XAML XAML: <Grid xmlns:x="http://schemas.microsoft.com/client/2006" x ...

  4. C#使用IconFont字体图标的动态加载(&#xe格式转换)

    IconFont 矢量字体图标由于文件小,资源多,可任意放大缩小不失真,方便着色等特点,在网页.Winform.WPF中被广泛使得.网页上介绍使用的文件很多,但动态加载并不多,本文将重点介绍利用C#语 ...

  5. js 动态加载select触发事件

    动态加载select后,手动调用一下 subjectChange函数,模拟触发change事件 function hallidChange(value) {$.ajax({type: "po ...

  6. cascader 动态加载 回显_ElementUI cascader级联动态加载回显和搜索看这个就够了

    这一篇是上一次讨论cascader级联动态加载回显问题的延续,文末有链接. 以下是思考和开发的过程,不感兴趣可以直接看使用文档. https://github.com/zhuss/lazy-casca ...

  7. C#动态加载DLL(转)

    利用反射进行动态加载和调用. Assembly ass=Assembly.LoadFrom(DllPath); //利用dll的路径加载 加载dll后,需要使用dll中某类. Type type=as ...

  8. 利用反射实现类的动态加载

    为什么80%的码农都做不了架构师?>>>    //首先定义一个接口来隔离类: public interface Operator { // public java.util.Lis ...

  9. 利用 JQuery的load函数动态加载页面

    利用JQuery的load函数动态加载页面 JQuery有好多Ajax函数,其中load是用来动态加载一个页面的内容到指定的dom元素上. 我们来做个例子: 做一个上下(左右)结构的页面,其中下左部分 ...

最新文章

  1. 5亿整数的大文件,怎么排?
  2. android studio没有org.apache.http.client.HttpClient;等包问题 解决方案
  3. C++ 术语(C++ Primer)
  4. numeric column can contains null
  5. LeetCode(235)——二叉搜索树的最近公共祖先(JavaScript)
  6. MVC中关于JSON的处理
  7. 倍福--软件界面介绍
  8. cad10版计算机快键在哪,CAD快捷键大全在哪里看?CAD快捷键大全与CAD技巧汇总
  9. java正整数分解因数_java如何将一个正整数分解质因数
  10. 走向面试之数据库基础:一、你必知必会的SQL语句练习-Part 2
  11. swagger 怎么去掉get delete_橡皮擦英文单词怎么读
  12. Swift不深入只浅出入门教程-孟祥月-专题视频课程
  13. 2012-2013年世界大学计算机专业排名
  14. Cisco(64)——路由策略综合
  15. hive的UDF函数的使用。常见UDF函数
  16. linux 文件操作write详解
  17. ASP实现自动发邮件
  18. 笔试题目---描述在浏览器中敲入一个网址并按下回车后所发生的事情
  19. php足疗预约,足浴养生管理系统轻松实现各种线上预约功能?
  20. ENVI5.3.1,按经纬度裁剪影像

热门文章

  1. 【mybatis源码分析(四)】mybatis事务实现原理
  2. Go 模板库:性能比较
  3. 2个阶乘什么意思_2的阶乘的阶乘是什么啊?就是2!!代表的什么意思?怎样计算?谢谢...
  4. 基于DCGAN动漫头像生成的课题意义200字
  5. 2021-2022-2 ACM集训队每周程序设计竞赛(1) - 问题 E: 祖玛的复仇 - 题解
  6. 认真CS☀️初始化数组元素、foreach语句
  7. 计算机辅助数学教学赛课总结,利用信息技术辅助数学教学的体会论文
  8. 20170518关于zabbix监控路由器交换机
  9. PoS淘金热潮,全节点对于分布式网络到底意味着什么?
  10. 关于软件开发,都应该知道的10个常识