简体   繁体   English

C#Winform按名称动态加载usercontrols

[英]C# Winform dynamically load usercontrols by name

I want to know if it's possible to dynamically load user controls? 我想知道是否可以动态加载用户控件?
This is some code to show what I mean: 这是一些显示我的意思的代码:

public void Load()
        {

            Reset();

            if (_host.User == null)
                return;

            int _count = 0;

            String[] _applications = _host.User.Applications;

            if (_applications == null)
                return;

            foreach (String _application in _applications)
            {

                TabPage _page = null;

                switch (_application)
                {
                    case "SF01":

                        _page = new TabPage();
                        _page.Text = "SF01";
                        _page.Controls.Add(new SF01(_container));

                        break;
                }

                if (_page != null)
                {

                    tapplications.TabPages.Add(_page);
                    m_list.Add(_count, _page);
                    _count++;

                }

            }

            tapplications.TabPages.Add(tlog);

            if (_host.User.Admin)
                tapplications.TabPages.Add(tadmin);

            _container.Controls.Add(this);

        }

As you can see SF01 is my usercontrol. 如您所见, SF01是我的用户控件。
Now how do I go about loading other usercontrols by name instead of hard typing the class object? 现在我如何通过名称加载其他用户控件而不是硬键入类对象?
This way I can create more applications and forget about how to load them. 这样我可以创建更多的应用程序,忘记如何加载它们。 ( case "SF01": ) case "SF01":

All the applications will reside beneath a project folder applications , maybe there is a way to iterate through that project folder? 所有应用程序都将驻留在项目文件夹applications ,也许有一种方法来遍历该项目文件夹?

项目

Yes it is. 是的。

A User Control can be instanciated using Activator.CreateInstance , as any other kind of object. 用户控件可以使用Activator.CreateInstance进行实例化,就像任何其他类型的对象一样。

string objTypeName = "myNamespace.UI.SF01"; // Full namespace name
SF01 myNewSF01 = (Foo)Activator.CreateInstance(Type.GetType(objTypeName));

Then you can replace your switch statement with 然后你可以用你的switch语句替换

_page = new TabPage();
_page.Text = "SF01";

var control = (Control)Activator.CreateInstance(Type.GetType("myNamespace." + _application));
_page.Controls.Add(control);

I found a (simpler) Solution by using reflection. 我通过使用反射找到了一个(更简单的) 解决方案

foreach (String _application in _applications)
            {

                TabPage _page = null;

                Type[] _atypes = new Type[] { typeof(Panel) };
                Object[] _avalues = new Object[] { _container };
                ConstructorInfo _ctor = Type.GetType("SFM." + _application).GetConstructor(_atypes);
                Object _control = _ctor.Invoke(_avalues);

                if (_control != null)
                {
                    _page = new TabPage();
                    _page.Text = _application;
                    _page.Controls.Add((Control)_control);
                }

                if (_page != null)
                {

                    tapplications.TabPages.Add(_page);
                    m_list.Add(_count, _page);
                    _count++;

                }

            }

Everything now works as expected! 现在一切都按预期工作!
Just need to do more error protection (Invoke fail, ...) 只需要做更多的错误保护(调用失败,...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM