前几天,我问了how to create a message box in your class,但其中一个答案说这不是正确的做法。我明白这是因为它真的打败了一个阶级。
我的程序从字符串文件中逐字逐句读取,并检查每个单词是否在数据库中。我想将未找到的每个单词放在表单上的ListBox中,这可以有多个选择。
每次找到新单词时,如何将该数据发送回表单?
答案 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 */);
}
}