在课堂和表格之间发送数据?

时间:2009-04-07 20:18:48

标签: c# forms class

前几天,我问了how to create a message box in your class,但其中一个答案说这不是正确的做法。我明白这是因为它真的打败了一个阶级。

我的程序从字符串文件中逐字逐句读取,并检查每个单词是否在数据库中。我想将未找到的每个单词放在表单上的ListBox中,这可以有多个选择。

每次找到新单词时,如何将该数据发送回表单?

4 个答案:

答案 0 :(得分:1)

我建议你做一个像这样的方法:

/* ... */

public IEnumerable<string> FindMissingWords(
                               string fileName, IEnumerable<string> toSearch)
{
    List<string> missingWords = new List<string>();

    // todo: the appropriate code for looking up strings in the file, using 
    // the filename and the strings that we passed into the function.

    // if you find one, add it to missingWords

    return missingWords;
}

然后从表单中调用该方法,并将它返回的每个字符串添加到您的框中。

(如果你不熟悉IEnumerable,不要担心 - 它只是一个定义一系列事物的接口,比如一个数组或一个列表。你可以传递一个字符串数组,但它会不那么精确。)

答案 1 :(得分:1)

如果类有对表单的引用,它可以直接更新表单。

someForm.SomeListBox.Items.Add(someWord);

如果表单有对类的引用,则可以让类引发类似

的事件
public delegate string WordNotFoundHandler(string word);
public WordNotFoundHandler event WordNotFound ;

并让表单处理该事件

theClass.WordNotFound += AddItemToListBox

void AddItemToListBox(string word)
{
someListBox.Items.Add(word);
}

这样做的好处而不是一个返回所有单词的大调用,它提供了更快的ui响应时间,特别是当由单独的线程完成时

答案 2 :(得分:0)

这就是我要做的(或类似的):

    bool done = false;
    while(true)
    {
        string foundstring;
        done = searchforstring(out foundstring);
        if(done)
            break;
        // Not done, so take what we found and add it to the listbox
        this.BeginInvoke(new Action<string>(delegate(string input)
            { this.listBox.BeginUpdate(); this.listBox.Items.Add(input); this.listBox.EndUpdate(); }),
            new object[] { foundstring });

        }

替换列表框控件的名称,我认为这样可行。或者您可以将匿名方法分解为自己的对象。我们的想法是,每次找到新字符串时,都会调度一个worker来执行“主应用程序线程”中的更新(因此是BeginInvoke()调用)。如果必须使用begin / endUpdate()调用,我就不会起诉,但它们可能是。

显然你如何获取字符串取决于你,但这应该是即使你的应用程序是多线程的,即时进入列表框的方法。如果它不是多线程的,直接的Invoke()(而不是BeginInvoke)应该可以立即更新列表框,但这可能会降低搜索性能。

答案 3 :(得分:0)

您不希望结合您的表单与搜索和查找文件中的单词的类。 这是基于事件的解决方案

基本上你需要做的是在类中公开一个事件,该事件从文件中读取和查找单词(我将其命名为WordFinder以进行说明。)

WordFinder公开了一个名为WordFound的事件,当发现新词时会引发该事件。

public class WordFinder
{
    public event EventHandler<WordFoundEventHandler> WordFound = delegate { };
    public event EventHandler NoWordsFound = delegate { };

    protected virtual void OnWordFound(WordFoundEventHandler e)
    {
        var wordFoundHandler = WordFound;
        wordFoundHandler(this, e);
    }

    private void OnNoWordsFound(EventArgs e)
    {
        var noWordsFoundHandler = NoWordsFound;
        noWordsFoundHandler(this, e);
    }

    public void FindWords(string fileName)
    {
        //.. read file and find word
        //.. When a word is found,
        OnWordFound(new WordFoundEventHandler(foundWord));

        // Keep a counter somewhere and check if any words has been found, 
        // if no words are found, then raise "NoWordsFoundEvent"
        OnNoWordsFound(EventArgs.Empty);
    }
}

public class WordFoundEventHandler : EventArgs
{
    public string FoundWord { get; private set; }

    public WordFoundEventHandler(string foundWord)
    {
        FoundWord = foundWord;
    }
}

现在,您的表单只会注册到WordFinder的事件,并在找到新单词时添加新项目。

public partial class Form1 : Form
{
    private readonly WordFinder _WordFinder;

    public Form1()
    {
        InitializeComponent();

        _WordFinder = new WordFinder();
        _WordFinder.WordFound += WordFinder_WordFound;
        _WordFinder.NoWordsFound += WordFinder_NoWordsFound;
    }

    private void WordFinder_WordFound(object sender, WordFoundEventHandler e)
    {
        // Add item to the list here.
        foundWordsListBox.Items.Add(e.FoundWord);
    }

    private void WordFinder_NoWordsFound(object sender, EventArgs e)
    {
        MessageBox.Show("No words found!");
    }

    private void findWordsButton_Click(object sender, EventArgs e)
    {
        _WordFinder.FindWords(/* pass file name here */);
    }
}