【问题标题】:How to access a form component from another (referenced) Project in visual C# 2013?如何从 Visual C# 2013 中的另一个(引用)项目访问表单组件?
【发布时间】:2015-05-08 23:32:50
【问题描述】:

我正在尝试从 Visual Studio 社区 2013 中的另一个“引擎”项目更改我的“游戏”项目中 RichTextBox 中的文本,该项目已被“游戏”项目引用。我尝试访问的所有内容都不会通过 Intellisense 调出 RichTextBox,导致出现红线,并且“引擎”项目拒绝构建。

通过查看网站和 Google,我尝试将 RichTextBox 设为静态以及其他一些技巧,包括我自己想出的一个技巧——制作第三个项目并引用另外两个。一切都无济于事。

这应该是我现在拥有的代码的重要部分:

在 Game.cs 中,我有公开课:

namespace Game
{
    public partial class Game : Form
    {
        ...  //All the code for the form
    }
}

在 Game.Designer.cs 我有 RichTextBox 公开和静态:

namespace Game
{
    partial class Game
    {
        ... // All the other unimportant stuff
        public static System.Windows.Forms.RichTextBox rtbMessages; //I've fixed the errors this caused in InitializeComponent() already
    }
}

现在从我的“引擎”项目中,我将尝试这样的事情(简化但它显示了我正在尝试做的事情):

using Game;

nameSpace Engine
{
    public class Monster
    {
        ... // Properties, Constructor, etc.

        public static bool IsDead(string name, int currentHP)
            if (currentHP <= 0)
            {
                Game.rtbMessages.Text += String.Format("You have killed {0}.{1}", name, Environment.NewLine);
                return true;
            }

            return false;
        }
    }
}

我现在只使用我能够在网上找到的基本教程学习 C# 和面向对象编程 3 周,但从我所学的内容来看,我真的不知道为什么这行不通.我尝试将“Engine”的引用添加回“Game”,但我收到一条错误消息,指出这会创建循环依赖,因为“Game”已经引用了“Engine”。

这甚至可能吗?我开始怀疑了。

编辑:我错误地假设“项目”只是 VS 用于命名空间的名称。问题不在于它们在不同的命名空间中,而是在不同的项目中。因此三振出局。

【问题讨论】:

  • “我已经修复了这在 InitializeComponent() 中引起的错误” - 你能指定这些错误是什么吗?通常,您永远不应更改 *.Designer.cs 中的任何内容,因为该文件完全由所见即所得的设计师生成。
  • 嗯很难从您的代码中分辨出来,但存在许多潜在问题。 1:你有游戏命名空间和游戏对象,这会混淆智能感知 2:你是从引擎引用游戏富文本框?只是从对象的命名我想 Game 是前端,它知道富文本框控件等,而 Engine 是你的逻辑层,它可能只知道字符串和整数等
  • “循环依赖”问题听起来好像您的 Engine 和您的 Game 命名空间不仅仅是不同的命名空间,而是代码实际上位于不同的程序集/不同的项目中?如果是这样,你应该在你的问题中指出这一点。
  • 这也是无效的Game.rtbMessages += String.Format("You have killed {0}.{1}", name, Environment.NewLine); 您正在尝试使用带有String 类型和RichTextBox 类型的+= 运算符应该是Game.rtbMessages.Text += String.Format("You have killed {0}.{1}", name, Environment.NewLine);
  • 1) namespace 只有一个作用:对类型和其他命名空间进行分组;它不会以任何方式影响类型之间成员的可访问性。 2) 请阅读stackoverflow.com/help/mcvestackoverflow.com/help/how-to-ask 以获取有关如何改进您的问题以使其有意义且可以回答的建议。

标签: c# winforms reference namespaces


【解决方案1】:

依赖项(项目引用)只能是单向的。事实上,正如您所发现的,VS 非常努力地让您无法创建循环引用。

通常,“游戏”项目将引用“引擎”项目。不是反过来。引擎永远不需要知道游戏项目中的类型。

如果引擎确实需要了解游戏类型,那么架构有问题。游戏类型实际上应该是引擎类型,或者您编码到引擎中的功能是特定于游戏的并且应该在游戏项目中。

在您的情况下,功能(更新 rtbMessages 控件)属于游戏项目。所以从游戏代码中你应该做这样的事情:

if (Engine.Monster.IsDead("monster name", monster_hp)) {
    Game.rtbMessages.Text += String.Format("You have killed {0}.{1}", name, Environment.NewLine);
}

并从Monster.IsDead 函数中删除rtbMessages 更新。

此外,我会考虑进行另一项更改。
你真的需要Monster.IsDead 是静态的吗?大概你已经提到了怪物。 Engine.Monster 类型上的非静态 IsDead 方法可能更有意义。您甚至可以将其设为 Engine.Monster 类的只读属性。

【讨论】:

  • 这就是我害怕的。我现在明白为什么这是一件好事了。似乎在那种情况下我将不得不重新考虑一些事情,但至少现在我现在为什么。谢谢大家的帮助,尤其是在这样一个新手问题上。
  • 实际上,经过一些重新排列后,我发现我根本不需要Engine.Monster.IsDead。感谢您提出将其设为只读属性的建议,但在我意识到我不需要它之前,我将采用这种方式对其进行编码。
猜你喜欢
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多