C# 如何在循环过程中要求用户(通过表单)从另一个类输入?

C# 如何在循环过程中要求用户(通过表单)从另一个类输入?,c#,visual-studio,C#,Visual Studio,如何从类库中的方法中填充表单?在下面的例子中,Method1()是关于什么的 Project "UI", Windows Forms Application reference to MyLib public class Form1 : Form { ... call some methods from MyLib.MyClass ... } Project "MyLib", Class Library public class MyClass { ... pu

如何从类库中的方法中填充表单?在下面的例子中,Method1()是关于什么的

Project "UI", Windows Forms Application
reference to MyLib
public class Form1 : Form
{
   ...
   call some methods from MyLib.MyClass
   ...
}

Project "MyLib", Class Library
public class MyClass
{
   ... 
   public void Method1()
       {
           loop through an array and ask user to validate some data on the form during each iteration
       }
}
更新: 更具体地说,MyLib库包含一个类,该类将把.csv文件加载到一个数组中(对于每一行,该数组将被添加到
列表中),然后在
列表中循环查找“可能的”重复项。无论何时发现一条记录,都需要向用户(在表单上)显示这两条记录,以最终确定它们是否相同

如何从类库中的方法中填充表单

真正的问题是你为什么要这么做?图书馆不应该对这样的事情负责。这是特定于工作流和UI的逻辑,而不是库通常用于的逻辑。库应该提供有用的数据结构,但是特定于应用程序的事情(比如收集输入并决定如何处理输入)应该由代码处理

无论如何。。。说这个我觉得有点脏。。。您总是可以将对表单类型的引用作为参数传递给该方法(这种方法将紧密耦合两个程序集,使其中一个程序集在没有其他程序集的情况下不可用)


抖动

您可以使用交叉/循环引用,但由于几个原因,这是不可取的


您还可以在类库中声明一个表单类型对象(如果是静态的话更好),并将该表单作为引用传递,如果我没有弄错的话,您可以通过成员“controls”调用该引用变量中的子控件。

即使Ed输入了最后的注释,也不要这样做!当然有可能,但这毫无意义。抵制诱惑

库应实现一些通用功能,即提供数据结构、逻辑方法或p/Invoke方法。但在表单类中,用户界面的逻辑所在。只需在Form1中创建一个方法来处理验证。这将更容易、更清晰。

这是一个巨大的问题

最简单的方法是在类库中添加对System.Windows.Forms的引用。然后,将窗口作为参数传递给业务类。 尽管这个解决方案很简单,但它不是一个干净的方法。在干净的分层体系结构中,不能在下层中使用上层对象。它既可能是编译的挑战,也可能是维护的黑洞。此外,单元测试这种情况是复杂的

考虑到这一点,另一个更复杂的解决方案是使用控制反转,使用Unity、Mef或任何其他框架,甚至手动执行

主要思想是在类库中创建一个定义用户交互的接口,如下所示:

public interface IInputValidator {
     bool IsValid(MyClass itemToValidate);
}
然后,在windows窗体应用程序中,实现以下界面:

public class Form1 : Form, IInputValidator {

    public void CallBusinessClass() {
        var myObj = new BusinessClass(this); // the key of the concept is here
        myObj.Iterate();
    }
    public bool IsValid(MyClass itemToValidate) {
        return MessageBox.Show("Is valid ?", MessageBoxButtons.YesNo) == MessageBoxButtons.Yes);
    }
}    
那么,在你的商务舱里:

public class BusinessClass {
    private IInputValidator m_validator;
    public BusinessClass(IInputValidator validator) {
        this.m_validator = validator;
    }

    public void Iterate()
    {
        foreach(var item in ItemsToIterate)
        {
            var isValid = m_validator.IsValid(item); // call the upper layer from a lower layer
        }
    }
}

希望这有帮助

如果类库MyLib被认为是通用的和后端的,因此与UI无关,那么它应该对UI元素或MessageBox以及用户交互一无所知,我认为您应该将验证逻辑移到UI,并只将验证/良好输入传递到库。@Davide Piras-IMHO库也应该处理验证,因为验证通常是将传递的数据与UI未配备的其他数据进行比较,除非您指的是“不正确的日期格式”类型的验证。UI应处理解析等,即语法验证,但逻辑、语义验证应由数据库处理。验证库中的输入/输出与验证用户输入之间存在差异。UI/模型层应该真正负责用户输入验证,因为只有它知道“业务”规则。@Ed S.-我不明白,假设您有一条业务规则“所有传出文档的状态都应为已批准”。谁应该执行验证规则,UI/模型还是BL?我认为BL,因为UI的错误验证(可能是仲裁,外部开发的)可能会导致数据存储中写入逻辑错误的数据;只是我不认为这个单独的程序集是一个业务层。也许我看错了评论。没问题。老实说,有时候学习相对抽象的设计原则最好的方法就是在第一次(几次)犯错。就我个人而言,直到我写了一个如此扭曲和不可维护的应用程序,我才真正“理解”多态性,直到我看到它是一个多么强大的概念。如果你能从建议中学习,那就太好了。如果没有,就和我们其他人一样受苦,直到一个清晰的时刻降临到你身上。+1代表“开始几次做错”。这是在现实生活中学习编程的唯一方法,尤其是在架构方面。是的,就像我说的。。。肮脏的,肮脏的建议。希望我的评论能对他有所帮助。