Как узнать, создана ли какая-либо форма в приложении C #? - PullRequest
0 голосов
/ 11 мая 2019

Я знаю, что есть обработчики событий для классов, которые наследуются от класса формы. Используя эти события, мы можем понять, создана ли форма или нет. например обработчик события Form Load. Я работаю над почти масштабным проектом, который состоит из слишком многих форм. В этом проекте пользователь может создавать несколько рабочих областей и открывать различные формы в каждой рабочей области. Когда пользователь закрывает рабочее пространство, все связанные формы должны быть закрыты. Для реализации этой функции я рассмотрел словарь с ключами идентификатора рабочей области, значения которых являются связанными открытыми формами. Поэтому я должен добавить значения, когда пользователь открывает формы. это можно сделать, если я добавлю строковый код в каждый обработчик события, загруженный формой, но это займет время Я хочу знать, могу ли я понять, что форма открывается из основной формы.

p.s: Я знаком с приложением. Работает. это не полезно в этом сценарии.

Ответы [ 2 ]

3 голосов
/ 11 мая 2019

В прошлом у меня была похожая проблема, первое, что пришло мне в голову, было использовать System.Reflection, но это невозможно, потому что вы не можете определить во время выполнения, какой экземпляр был создан.

Я не нашел никакого «волшебного» решения для этой проблемы, но самым простым и безопасным решением, которое я нашел, было расширение базового класса Form (до моего пользовательского SuperForm) и использование этого базового класса для координации и обновления. статический список всех экземпляров этого базового класса (путем переопределения методов OnLoad() и OnClosed()).
Очевидно, что все заявки должны наследоваться от SuperForm.

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

Вот пример архитектуры:

Класс SuperForm:

public class SuperForm : Form
{
    private bool _isFormActive = false;
    public bool isFormActive
    {
        get
        {
            return this._isFormActive;
        }

        set
        {
            this._isFormActive = value;
        }
    }

    protected override void OnLoad(EventArgs e)
    {
        this.isFormActive = true;
        AppForms.Add(this);
        base.OnLoad(e);
    }

    protected override void OnClosed(EventArgs e)
    {
        this.isFormActive = false;
        AppForms.Remove(this);
        base.OnClosed(e);
    }
}

Статический класс со статическим списком для обработки экземпляров форм приложения:

public static class AppForms
{
    private static List<SuperForm> _AppFormsList;
    public static List<SuperForm> AppFormsList
    {
        get
        {
            if (_AppFormsList == null)
            {
                _AppFormsList = new List<SuperForm>();
            }
            return _AppFormsList;
        }
        set
        {
            _AppFormsList = value;
        }
    }

    public static void Add(SuperForm instance)
    {
        AppFormsList.Add(instance);
    }
    public static void Remove(SuperForm instance)
    {
        AppFormsList.Remove(instance);
    }
}

Реализация:

public partial class Form1 : SuperForm
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {   
        // you dont have to use polymorphism...
        SuperForm f = new Form2();
        f.Show();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        // you dont have to use polymorphism...
        SuperForm f = new Form3();
        f.Show();
    }

    private void button3_Click(object sender, EventArgs e)
    {
        // show all the forms that are active
        foreach (var frm in AppForms.AppFormsList)
        {
            MessageBox.Show(((SuperForm)frm).isFormActive.ToString());
        }
    }
}
1 голос
/ 13 мая 2019

Спасибо @Jimi и @TnTinMn.Самое простое решение (требующее меньше усилий) - это использование WindowOpenedEvent .Этот слушатель события идентифицирует окно, которое было открыто.Стоит отметить, что при открытии любого окна в вашей операционной системе это событие вызывается.Мы можем сравнить идентификатор процесса открытого / созданного окна с идентификатором процесса нашего приложения, чтобы понять, какая форма связана с приложением.Обратите внимание, что UIAutomationClient и UIAutomationType DLL должны быть добавлены в проект.Эти DLL находятся в: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\UIAutomationClient.dll

Я добавил ниже код в файл Program.cs.

           MainForm mainForm = new MainForm();
           Automation.AddAutomationEventHandler(
           WindowPattern.WindowOpenedEvent, AutomationElement.RootElement,
           TreeScope.Subtree, (uiElm, evt) =>
           {
               AutomationElement element = uiElm as AutomationElement;
               if (element == null) return;
               try
               {
                   if (element.Current.ProcessId == Process.GetCurrentProcess().Id)
                   {
                       IntPtr elmHandle = (IntPtr)element.Current.NativeWindowHandle;
                       Form form = Application.OpenForms.OfType<Form>()
                           .Where(f => (f.AccessibilityObject as Control.ControlAccessibleObject).Handle == elmHandle)
                           .FirstOrDefault();
                       mainForm.UpdateTabFormsDict(form); // adding a open form to the current tab
                   }
               }
               catch (ElementNotAvailableException)
               { /* May happen when Debugging => ignore or log */
               }
           });

Для получения дополнительной информации вы можете увидеть Запустить событие, когда любая Форма загружается .WindowPattern также предоставляет WindowClosedEvent .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...