【问题标题】:Is it possible to define a class-scope objet from a method?是否可以从方法定义类范围对象?
【发布时间】:2011-10-26 13:47:49
【问题描述】:

这似乎完全不合理,但我一直在设计一个多面板的真实设备模拟器,它有许多不同的屏幕,我目前的方法是仅从代码中添加所有屏幕对象,并在我处理时处理它们切换到另一个屏幕。

我有一些固定对象,它们是已经定义并就位的真实设备按钮。问题是,我在方法中分离每个面板构造,例如:buildLogin()buildMainScreen() 等,我需要从这些方法中编辑一些屏幕对象,比如将启用的功能标签的颜色更改为如果启用则为绿色,如果禁用则为白色。

我的问题是:是否可以从一个可在整个类中访问的方法中声明一个对象,就像在变量声明部分中定义它一样?它类似于 PHP 中的 GLOBAL。

我不能像往常一样在所有东西之上声明它,因为当我处置对象时,我无法“重新创建”它们,因为育儿或重用处置的对象或其他东西。 ..

[编辑] 示例代码:

public partial class frmMain : Form
{
    //I could as well do this:
    //Button button1 = new Button();

    public frmMain()
    {
         buildLogin();
    }

    private void buildLogin()
    {
        Panel panel1 = new Panel();
        Controls.Add(panel1);

        //But then, there is no way to do this:
        // if (button1.IsDisposed == true) //because of the panel, or smthing
        Button button1 = new Button();
        panel1.Controls.Add(button1);

        button1.Click += (s, f) => { panel1.Dispose(); buildMainMenu(); };
    }

    private void buildMainMenu()
    {
        Panel panel2 = new Panel();
        Controls.Add(panel2);

        Button button2 = new Button();
        panel2.Controls.Add(button2);
    }

    //This was created from the Designer and is class-scoped
    private void btn_Frame_TSK1_Click(object sender, EventArgs e)
    {
        //Here, I have no access to the objets I've created programatically.
        //button1.Text = "Text changed!";
    }
}

【问题讨论】:

  • 这个设计肯定有问题,提供一些代码,例如您如何创建屏幕以及何时需要访问这样的全局对象?
  • 您是否考虑过使用面向对象的设计?这使它变得容易得多。
  • 我对你所追求的有点模糊 - 你能不能只声明一个类范围的属性/字段,然后在你的方法中设置它?未能进行重构以将内容作为参数传递,然后您可以对其进行修改...听起来您的程序结构可能是此处需要更改的内容...
  • 为什么不直接使用设计器?在那里添加控件,默认不可见,并根据需要使其可见。存储控件的字段将位于部分类的自动生成部分中。
  • 在 Alpha 版本中做到了这一点,但是很难跟踪近 400 个对象和 30 个不同的屏幕,不是吗?此外,我得到了许多屏幕闪烁,我可以通过这种方法将其消除。

标签: c# class scope local


【解决方案1】:

如果您想确保事情始终是完全动态的并且始终在背后的代码中完成,您可能需要查看在 Controls 集合中搜索您创建的控件。

例如,请确保为 button1 提供一个 ID 值 (button1.ID="textUpdatedButton"),该 ID 值将与您创建的其他控件唯一地标识它。然后使用 FindControl 或在 Controls 集合中搜索以在事件处理程序中找到具有您要定位的 ID 的控件。

//This was created from the Designer and is class-scoped
private void btn_Frame_TSK1_Click(object sender, EventArgs e)
{
    Control control = this.FindControl("textUpdatedButton");
    if(control != null && control is Button){
        Button button1 = (Button)control;
        button1.Text = "Text changed!";
    }
}

或者,为了让事情看起来更像一个变量,您可以使用属性来隐藏控件结果(如前所述):

private Button Button1 {
    get { return (Button)this.FindControl("textUpdatedButton"); }
}

//This was created from the Designer and is class-scoped
private void btn_Frame_TSK1_Click(object sender, EventArgs e)
{
    if(this.Button1 != null){
        this.Button1.Text = "Text changed!";
    }
}

实际实现会因您构建控件的方式而异,但本质上,如果您需要这样做,这种方法可以让您在代码中动态构建所有内容。请记住使用标识符让您以后找到东西。

【讨论】:

    【解决方案2】:

    在类级别将您的对象定义为静态。这样它就可以从类的所有实例的所有方法中访问(释放一个实例不会影响它)。

    【讨论】:

    • 不,仍然说我无法访问“panLoginMenu.Controls.Add(btnRemember);”这一行中的已处置对象btnRemember 是静态控件...
    猜你喜欢
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    相关资源
    最近更新 更多