从另一个项目修改Windows窗体控件



我在用户控件MainScreen中有一个控件lblDate。我想在Date班的一个方法中修改它,这个方法在另一个项目AoWLibrary中。我不能引用它,因为AoWLibrary是第一个项目的依赖项。

我试图使lblDate静态,但编译器一直向我抛出错误,我有一个公共属性,日期似乎无法访问:

    public Label LabelDate
    {
        get { return lblDate; }
        set { lblDate = value; }
    }

在Date类中,我需要公共方法CalculateDate来修改lblDate的Text属性

    public static void CalculateDate()
    {
        GameDate = month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString();
    // LabelDate.Text = GameDate;
    // This is essentially what I need to do
    }

而且,我甚至不能在同一项目的其他控件中访问lblDate。

所以,一般的想法是您需要跟踪范围内的内容。有很多方法可以用来做你想做的事情,但是它们中的任何一个都依赖于对象之间正确的引用,而这些引用的方式你可能还没有完全理解。别担心——每个人在某些时候都要解决这个问题。

当您试图将该成员设置为静态时,编译器报错的原因是标签本身不是静态的。绑定到MainScreen的单个实例,它在静态上下文中没有任何意义,根据定义,静态上下文中是没有任何对特定MainForm的固有引用的作用域。

当然,你的Date类也是一个完全不同的上下文,但是它的非静态成员确实可以访问Date的实例。在创建之前,这两个上下文之间没有任何路径。静态路由实际上可以工作(查看Singleton模式:其思想是静态存储类的第一个也是唯一一个实例,并从其他地方引用它),但可能不是好的设计。其他方法是将MainScreen的实例(最好是通过接口)甚至LabelDate本身传递给Date。所有这些都可以让你把谈话所需的两个部分放在一起。

然而,我想建议你考虑一下你的游戏状态存储在哪里。是在库中还是在消费程序集中?如果是前者,您可能想要考虑为需要在库类中存储和操作的数据创建一个完整的无线程模型,并且只在主应用程序中使用现成的数据。另一种选择是,您的模型驻留在主应用程序中,只在必要时回调库。在这种情况下,你现在可能应该坚持向库请求答案(或者最多监听库中的事件),而不是期望它自己返回应用程序(无论是获取还是提供信息)。

在弄清楚如何做到这一点后,您可能会发现您的范围管理问题更容易处理。即使是一点点好的架构也能大有作为。

但如果这一切都有点压倒性的,不要强调太多。听起来你这样做是为了好玩,这是一个很好的学习方式。你会遇到这样的问题,你可能会遇到一个好的设计,也可能会遇到一个不太好的设计,但无论如何,你都在与重要的概念搏斗,并且会因此而变得更好。

属性LabelDate来自你的userControl MainScreen的类,但是你没有创建任何userControl..您希望修改主屏幕的哪个实例?

你应该做

this.controlMainScreen.LabelDate = GameDate;

考虑到你在评论中所说的,你有

 FormMain.Designer.cs there is: this.controlMainScreen = new Adventurers_of_Wintercrest.UserControls.MainScreen();

我宁愿建议你让你的GameDate方法返回一个字符串,然后从你的主项目中调用它,这就是本质上库的意义所在。例如:

public static string CalculateDate()
{
    return month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString();
}
//in your main project
LabelDate.Text = myLibrary.CalculateDate();

为了从同一项目中的其他控件访问它,你应该使用一个委托-提供一个执行添加的委托,声明委托并从你的CaculateDate调用函数。例子:

public delegate void dateSet(string);
public void setDate(string date)
{
    labelDate.Text = date;
}

然后在你的CaculateDate方法中:

labeldate.Invoke(new MainForm.dateSet(), GameDate);

最新更新