基本上我有2个项目,一个表单和一个用户控件。
我需要它们都在不同的项目中,但是表单需要引用用户控件,因为它使用的是用户控件。并且用户控件将需要使用表单类之一来引用表单。当我添加第二个因为它需要时,VS会抱怨循环依赖,这是可以理解的。我该如何解决这个问题?
答案 0 :(得分:2)
逻辑上,表单应取决于用户控件。您可以创建一个接口来替换用户控件项目中的表单,然后让表单实现该接口。
示例用户控制项目;
public interface IForm
{
string MyString { get; }
}
public class MyUserControl : UserControl
{
public IForm Form { get; set; }
private void ShowMyString()
{
String myString = Form.MyString;
...
}
}
示例表单项目
public class MyForm : Form, IForm
{
public MYString { get "My String Value"; }
}
答案 1 :(得分:2)
我认为问题的根本原因是您没有正确区分表单和控件之间的问题。
由于你有一个(有点通用的)控件,它不应该依赖于表单。控件的所有逻辑都应该驻留在控件本身内。表单应该只使用黑盒子来控制:添加它,设置公共字段,调用公共方法等等。其他任何东西都违反了封装。
有时,控件可能需要了解其父表单的内容。在这种情况下,我建议一些简单的事情,如向子控件添加Parent
字段。
如果您需要表单中更具体的内容,您可以随时添加界面;界面应该只列出控件从表单中需要的东西。例如,如果您需要大小,可以添加:
public interface IControlParent {
int Width { get; }
int Height { get; }
}
通过这种方式,您可以清楚地看到依赖项(控件需要父项的内容),如果父类型/合同发生更改,则您不需要执行更改控制类的操作。
答案 2 :(得分:0)
你必须对你的代码进行分离,对于应用程序集的引用绝不是一个好主意,如果你将来尝试重用它,应用程序exe应该与控件一起使用。
因此,从表单项目中获取类并将其移动到控件项目或创建库项目,将类放在其上并从控件和应用程序项目中引用它。
答案 3 :(得分:0)
您应该使用事件(委托)。我们假设您在表单项目中创建了一个类:Form1。在用户控件内部,您定义了UserControl1。 UserControl1需要实例化并从Form1调用方法:
public class Form1
{
public void Execute(string sMessage)
{
Console.WriteLine(sMessage);
Console.ReadLine();
}
}
的UserControl1:
public class UserControl
{
public Func<object, object> oDel = null;
public void Execute()
{
oDel?.Invoke("HELLO WORLD!");
}
}
从实例化UserControl的类中,我们称之为ParentClass:
public class ParentClass
{
public void Execute()
{
UserControl oUserControl = new UserControl();
oUserControl.oDel = Form1Action;
oUserControl.Execute();
}
public object Form1Action(object obj)
{
string sObj = Convert.ToString(obj);
Form1 oForm = new Form1();
oForm.Execute(sObj);
return null;
}
}
这种方法负责将事件处理到高级别课程。