开发者

How to ask user for input (through Form) from another class during a loop?

开发者 https://www.devze.com 2023-02-11 15:38 出处:网络
How do I populate a Form from within a method in a class library? So in the example below Method1() is what\'s it about.

How do I populate a Form from within a method in a class library? So in the example below Method1() is what's it about.

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
       }
}

UPDATE: To be more specific, the MyLib library 开发者_如何学Ccontains a class that will load a .csv file into an array (which for each row will be added to a List<string[]>) and than will loop through the List<string[]> looking for "possible" duplicates. Whenever one is found the user needs to be presented (on a Form) with both records to ultimately decide if they are the same.


How do I populate a Form from within a method in a class library?

The real question is why would you want to? The library should not be responsible for something like this. This is logic specific to your workflow and UI, not something a library is typically used for. The library should provide useful data structures, but things that are specific to your application (like gathering input and deciding what to do with it) should be handled by your code.

Anyway... I feel a bit dirty saying this... you could always just pass a reference to your form type as an argument to the method (an approach that will, among other things, tightly couple the two assemblies, making one unusable without the other)...

shudder


You may use Cross/Circular-referencing but this is not advisable due to several reasons.

You may also declare a Form-type object(better if static) within the class library and pass that form as reference and you may call the child controls within that referenced variable through the member "Controls" if I'm not mistaken.


Even though Ed put that final comment in, DO NOT DO IT! Of course it's possible, but it makes no sense. Resist the temptation!

The library should implement some general functionality, i.e. provide data structures, logic methods or maybe P/Invoke methods. But in your form class is where the logical for your UI goes. Just make a method in Form1 to handle the validation. It would be a lot easier and a lot clearer.


It's a vast question.

The easiest way would be to add a reference to System.Windows.Forms in your class lib. Then, pass the window as an argument to your business class. But although easy this solution is, it's not a clean way. In a clean layered architecture, you can't use objects of upper layers in lowers layers. It can be both a challenge to compile and a maintenance black hole. Moreover, unit testing such cases are complex.

Considering this, another solution, a bit more complex, would be to use inversion of control, using a framework like Unity, Mef or any other, or even doing it manually.

The main idea would be to create in your class library an interface that defines user interactions like this :

public interface IInputValidator {
     bool IsValid(MyClass itemToValidate);
}

Then, in you windows form application, implement this interface :

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

Then, in you business class :

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
        }
    }
}

hope that helps

0

精彩评论

暂无评论...
验证码 换一张
取 消