WPF动态加载TabControl

主要讲一下如何通过点击菜单,实现动态加载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();
                }
            }
            //如果不存就添加一个TabItem
            if (!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();
                }
            }
            //如果不存就添加一个TabItem
            if (!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();
            }
        }

 

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF TabControl是一种常用的控件,用于在应用程序中创建多个选项卡。每个选项卡由TabItem表示,可以通过TabItem的Header属性设置选项卡的标题。 要给TabItem动态添加事件,可以使用以下步骤: 1. 在XAML中创建TabControl和一些初始化的TabItem。 2. 在代码中订阅TabControl的SelectionChanged事件。 3. 在该事件处理程序中,获取当前选中的TabItem。 4. 使用AddHandler方法为选中的TabItem添加所需的事件处理程序。 以下是实现的示例代码: XAML部分: ```XAML <TabControl x:Name="myTabControl" SelectionChanged="TabControl_SelectionChanged"> <TabItem Header="选项卡1" /> <TabItem Header="选项卡2" /> </TabControl> ``` C#部分: ```C# private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) { // 获取当前选中的TabItem TabItem selectedTabItem = (TabItem)myTabControl.SelectedItem; // 为选中的TabItem添加事件处理程序 selectedTabItem.AddHandler(Button.ClickEvent, new RoutedEventHandler(TabItem_ButtonClick)); } private void TabItem_ButtonClick(object sender, RoutedEventArgs e) { // 处理选中的TabItem的按钮点击事件 MessageBox.Show("点击了选项卡的按钮!"); } ``` 上述代码中,我们首先在XAML中创建了一个TabControl和两个TabItem,并为TabControl的SelectionChanged事件指定事件处理程序。 在事件处理程序中,我们首先获取当前选中的TabItem,然后使用AddHandler方法为其按钮的Click事件添加了一个事件处理程序。 在TabItem_ButtonClick方法中,我们可以处理选中的TabItem的按钮点击事件,并在此处显示了一个消息框,以示例展示处理逻辑。 通过上述步骤可实现给WPF TabControl的TabItem动态添加事件的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值