C # Загрузка UserControl из плагина - PullRequest
0 голосов
/ 12 ноября 2018

Это расширение моего предыдущего проекта плагина ЗДЕСЬ

Я все еще на стадии мозгового штурма, но идея довольно проста. Теперь, когда я могу создать библиотеку, загрузить ее в свое приложение в качестве плагина и получить систему обмена сообщениями назад и вперед, я пытаюсь сделать еще один шаг вперед и создать вкладку в форме моего основного приложения из плагина в управлять информацией.

Изначально, зная, что это не удастся, я попытался сериализовать UserControl как объект и пропустить его через систему плагинов, которая создаст вкладку, и десериализовать Control как содержимое вкладки.

Плагин Call

public interface PluginHost
{
    void AddTabView(string name, object view);
    ...
}

вызов программы

public void AddTabView(string name, object view)
{
    if (tabViews.InvokeRequired)
    {
        AddTabViewCallBack d = new AddTabViewCallBack(AddTabView);
        handle.Invoke(d, new object[] { name, view });
    }
    else
    {
        TabPage v = new TabPage();
        v.Text = name;
        tabViews.TabPages.Add(v);
        v.Controls.Add(view as UserControl);
    }
}

Причина этой ошибки в том, что UserControl не может быть сериализован, и, что более важно, он не может передать свой родительский элемент, как намекает ошибка System.Runtime.Remoting.RemotingException: 'Remoting cannot find field 'parent' on type 'System.Windows.Forms.Control'.'

Исходный вид в качестве примера enter image description here

Множество отчетов в моих исследованиях предлагают создать систему сценариев для процедурной интерпретации построения элемента управления, а не пытаться передать сам объект. Моим лучшим предположением было бы создание общего сериализуемого объекта, содержащего позиции, размер, имена, значения и любую другую соответствующую информацию, которую можно было бы передать обратно, а затем перебрать ее, чтобы сгенерировать желаемый UserControl.

[* 1 031 * TL; др * * тысяча тридцать две] * 1 033 *

Если это лучший метод, каковы мои варианты в отношении события (onclick, selection_changed и т. д.), чтобы минимизировать вздутие живота Плагин архитектуры.

Мне известно, что я не хочу заранее программировать каждый сценарий. ProxyDomain DOES содержит PerfMethod, который может позволять вызывать методы и функции из строкового имени из плагина, но я чувствую, что он может вызвать много чрезмерных обратных вызовов из Program-> Plugin-> Program-> Plugin.

PeftMethod (строковое имя метода, объект [] args, ListBox lvErrors)

public object PerfMethod(string methodname, object[] args, ListBox lvErrors)
{
    try
    {
        Type type = null;
        try { type = _assembly.GetType(typeof(FoxBot).Namespace + ".EventHandler"); }
        catch { }
        if (type != null)
        {
            MethodInfo method = type.GetMethod(methodname);

            if (method != null)
            {
                object ret = null;
                execute = new Thread(new ThreadStart(() =>
                {
                    try
                    {
                        object classInstance = Activator.CreateInstance(type, null);
                        if (method.GetParameters().Length > 0)
                        {
                            ret = method.Invoke(classInstance, args);
                        }
                        else
                        {
                            ret = method.Invoke(classInstance, null);
                        }
                    }
                    catch (ThreadInterruptedException)
                    {
                    }
                    catch (Exception e)
                    {
                        //lvErrors.Items.Add("<Scriptor> InvokeException: " + e.ToString() + ".");

                        MessageBox.Show(e.ToString(), "PerfMethod Failure",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                    }
                }));
                execute.Start();
                try
                {
                    while (execute.IsAlive)
                        Application.DoEvents(); //Thread.Sleep(100);
                }
                catch (Exception e)
                {
                    lvErrors.Items.Add("<Scriptor> MethodException: " + e.ToString() + ".");
                }
                return ret;
            }
            else
            {
                lvErrors.Items.Add("<Scriptor> MethodNotFound: " + methodname + ".");
            }
        }
        else
        {
            lvErrors.Items.Add("<Scriptor> TypeNotFound: " + (typeof(FoxBot).Namespace + ".EventHandler") + ".");
        }
        UnloadDomain();
    }
    catch (Exception er)
    {
        lvErrors.Items.Add(er.ToString());
    }
    return null;
}
...