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

时间:2013-05-10 02:44:13

标签: c# winforms

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

我试图让lblDate静态但是编译器一直在向我抛出错误,而且我有一个Date无法访问的公共属性:

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

在课程日期,我需要公共方法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。

3 个答案:

答案 0 :(得分:1)

所以,一般的想法是你需要跟踪范围内的内容。有很多方法可以做你想做的事情,但是他们中的任何一个都依赖于对象,这些对象以你可能还不太了解的方式正确引用。别担心 - 每个人都必须在某个时候解决这个问题。

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

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

但是,我建议您考虑一下您的游戏状态存储位置。是在图书馆还是消费大会?如果是前者,您可能需要考虑创建一个完整的GUI数据模型,该模型需要在库类中存储和操作,并且只在主应用程序中使用现成的数据。另一种方法是您的模型位于主应用程序中,并根据需要回调您的库。在这种情况下,您现在应该坚持要求图书馆寻求答案(或者至多是在库中监听事件)并且不要期望它自己回到应用程序(无论是获取还是提供信息)。

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

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

答案 1 :(得分:0)

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

你应该做

this.controlMainScreen.LabelDate = GameDate;

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

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

答案 2 :(得分:0)

我建议你让你的GameDate方法返回一个字符串,然后从你的主项目中调用它,这些基本上是库的意思。 e.g:

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);