在C#中调用父窗体中的方法并访问父窗体中的gui元素的最佳实践 [英] best practices to call methods in the parent form and access gui elements in parent form in c#

查看:50
本文介绍了在C#中调用父窗体中的方法并访问父窗体中的gui元素的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个win窗体应用程序,我发现自己不断需要访问父窗体中的方法,例如来自另一个类的Form1或Form类.我的窗体1的构造函数中有一些初始化程序,因此无法创建Form1的实例.因此,我无法访问Form1的方法.

I am developing a win form app and I found myself constantly requiring to access methods in my parent form say Form1 from another class be it a form class or just a class. I have some initializers in the constructor of my form 1 and hence I am not able to create an instance of the Form1. So I am not able to access the methods of Form1.

所以我觉得这是一个不好的做法.但是,在某些情况下,例如在这种情况下,我不知道还要做什么.我有一个称为ProcessData的类,其中有一个方法可以接收文件,逐行读取文件并处理数据.现在,我从主窗体Form1中将该方法作为线程调用.我的要求是数据处理,我想在主窗体Form1的多行文本框中显示当前正在处理的行.

So I feel like this is a bad practice. However, there are certain instances that I don't know what else to do for instance consider this scenario. I have a class called ProcessData in which I have a method which receives a file, reads it line by line and process the data. Now I'm calling this method as a thread from my main form Form1. My requirement is as the data process I want to show the line currently under process in a multiline textbox in the main form Form1.

以前我所做的一切都在同一Form1中完成,所以我使用了一个委托,例如

Previously what I did have I had everything in the same Form1 so I used a delegate, like

delegate void SetTextCallback(string text, Control ctrl);
private void SetText(string text, Control ctrl)
    {
        if (ctrl.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text, ctrl });
        }
        else
        {
            if (ctrl.GetType() == typeof(Label))
            {
                ctrl.Text = text;
            }
            else
            {
                ctrl.Text += Environment.NewLine + text;
            }
        }
    }

我像SetText("text",Label1);

and I invoked this like SetText("text",Label1);

但是,如果我从另一个类调用此方法来引用Label1,我将需要Form1的实例,但无法创建它,那么最佳实践是什么?

but if I am calling this from another class to refer Label1 I will need an instance of Form1 but I will not be able to create it, so what is the best practice to do it?

(我知道我可以将文本传递给SetText并在那里处理控件,但是我将对从不同类调用的各种文本框和标签控件使用相同的东西)

(I know I can just pass the text to SetText and handle the control there but I am going to use this same thing for a variety of textbox and label controls invoked from different classes)

推荐答案

我通常这样做的方法是让子窗体公开与该窗体上的逻辑操作和事件相对应的事件,例如:

The way that I normally do this is to have the child form expose events corresponding to the logical actions and events on that form, for example:

/// <summary>
/// Occurrs when an item is selected in the form
/// </summary>
public event EventHandler<ItemSelectedEventArgs> ItemSelected;

/// <summary>
/// Fires the <see cref="ItemSelected" /> event
/// </summary>
protected void OnItemSelected(MyItem item) 
{
    var handler = this.ItemSelected;
    if (handler != null)
    {
        ItemSelectedEventArgs args = new ItemSelectedEventArgs();
        args.Item = item; // For example
        handler(this, args);
    }
}

这个想法是,父窗体的逻辑应该响应子窗体上的动作,而不是子窗体上的动作来驱动父窗体上的动作-您应该尽可能地封装窗体逻辑(aka关注点分离).

The idea is that the logic of your parent form should respond to actions on your child form, rather than actions on your child form driving actions on the parent form - you should try to encapsulate the forms logic as much as possible (aka separation of concerns).

作为一种模式,它还应该是处理通过 InvokeRequired 等将呼叫编组到正确线程的父/调用形式,而不是子形式-除非没有必要,否则这是不必要的您正在后台线程上工作.

Also as a pattern it should be the parent / calling form that handles marshalling the calls across to the correct thread via InvokeRequired etc... rather than the child form - this will be unneccessary anyway unless you are doing work on background threads.

这篇关于在C#中调用父窗体中的方法并访问父窗体中的gui元素的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆