5

lblDate在 User Control 中有一个控件MainScreen。我想Date在另一个项目中的类中的一个方法中修改它AoWLibrary。我无法引用它,因为 AoWLibrary 是第一个项目的依赖项。

我试图使 lblDate 静态但编译器不断向我抛出错误,并且我有一个 Date 似乎无法访问的公共属性:

    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 。

4

3 回答 3

1

因此,总体思路是您需要跟踪范围内的内容。有很多方法可以去做你想做的事,但是它们中的任何一个都依赖于以你可能还不太完全理解的方式正确地相互引用的对象。别担心——每个人都必须在某个时候解决这个问题。

当您尝试使该成员成为静态时,编译器抱怨的原因是标签本身不是静态的。由于绑定到 MainScreen 的单个实例,它在静态上下文中没有任何意义,根据定义,静态上下文是一个范围,没有对特定 MainForm 的任何固有引用。

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

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

在弄清楚如何做到这一点时,您可能会发现您的范围管理问题更容易处理。即使是一点点好的架构也可以走很长的路。

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

于 2013-05-10T04:57:44.747 回答
0

属性 LabelDate 来自您的 userControl MainScreen 的类,但您没有实例化任何 userControl.. 您希望修改 MainScreen 的哪个实例?

你应该做

this.controlMainScreen.LabelDate = GameDate;

考虑到您在评论中说,您有

 FormMain.Designer.cs there is: this.controlMainScreen = new Adventurers_of_Wintercrest.UserControls.MainScreen();
于 2013-05-10T03:21:27.637 回答
0

我宁愿建议你让你的 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);
于 2013-05-10T03:50:54.950 回答