WinForms 和子表单 - 如何整合多余的“实用程序”代码?
我首先进行了搜索和谷歌搜索,认为肯定有人以前问过这个问题,但我确实找不到这个问题的良好描述。
我有六到八个类似的 C# .NET 2.0 WinForms 应用程序,它们是使用相当常见的主应用程序窗口模型构建的,其中包含多个 GUI 数据字段以及用于进一步收集数据的多个模式对话框。许多数据字段(尤其是文本框)具有相同的数据验证例程。我一遍又一遍地编写相同的 xxx_Validating() 例程,在最简单的情况下,仅将输入文本的第一个字符(如果有)大写并重新显示结果。我还有另一个邮政编码字段,它使用 1000 个成员的字符串数组获取 5 位美国邮政编码的前 3 位数字并返回相应的州。简单的东西。还有其他一些;这是一个例子:
public void CapFirstCharTextBox_Validating(object sender, CancelEventArgs e)
{
string strValue = ((TextBox)sender).Text.Trim();
if (strValue.Length >= 1) {
if (char.IsLower(strValue[0])) {
strValue = strValue.Substring(0, 1).ToUpper() + strValue.Substring(1);
((TextBox)sender).Text = strValue; // fires (whatever sender)_TextChanged()
}
}
}
这又是六个左右这样的“实用”例程的一部分。每个对话框类只有一组,并且该对话框中需要此功能的所有各种 TextBox 的 Validating 事件都指向相同的方法。所以这并不是说我在给定的源文件中有 20 个这样的文件(每个 TextBox 一个)或任何东西;整个对话框类只有一个。
问题是,整套这些都存在于我需要它们的每个源文件中。这是主窗口的一组,每个弹出对话框的更多组 - 这太多了。我知道模态对话框类无法相互通信,并且使所有这些东西全局化充其量是难以捉摸的,而最坏的情况则是一个很大的“禁忌”。
我成功地尝试将对“FormMain”(其中存在这些例程的一个副本)的引用传递给各种对话框构造函数,然后使用它们自己的验证处理程序调用这些验证例程。它有效,但感觉非常笨重,而且肯定不是最好的方法。
那么,我将如何(或者我想要)重新安排项目并更好地组织代码以仅拥有此类事物的单个实例?我如何连接此类方法的全局“实用程序”类,以便我可以从主窗体的代码以及一堆弹出模式对话框的代码中访问它?
如果可能的话,我想只维护一个可执行文件,而不需要额外的 .DLL(顺便说一句,这些都是每个解决方案一个项目),如果可行的话,我希望能够进一步共享该通用代码多种解决方案。
我认为答案将包括编写新的程序集,使用不同的命名空间(目前给定项目中的所有代码都包含在同一命名空间中),并且可能将这些内容分离到同一解决方案文件中自己的项目中。
是否可以?
I searched and Googled first, thinking surely someone must have asked this before, but I sure can't find a good description of this problem.
I have six or eight similar C# .NET 2.0 WinForms applications built with the fairly common model of a main application window with several GUI data fields plus several modal dialogs for further data collection. Many of the data fields (especially TextBoxes) have identical data validation routines. I'm writing the same xxx_Validating() routines over and over, which in the simplest case only capitalize the first character of the entered text (if any) and redisplay the result. I have another one for ZIP Code fields that takes the first 3 digits of a 5-digit US postal ZIP Code and returns the corresponding State, using a 1000-member string array. Simple stuff. There are a few others; here's an example:
public void CapFirstCharTextBox_Validating(object sender, CancelEventArgs e)
{
string strValue = ((TextBox)sender).Text.Trim();
if (strValue.Length >= 1) {
if (char.IsLower(strValue[0])) {
strValue = strValue.Substring(0, 1).ToUpper() + strValue.Substring(1);
((TextBox)sender).Text = strValue; // fires (whatever sender)_TextChanged()
}
}
}
Again this is part of a half-dozen or so such "utility" routines. I've only got one set of these per dialog box class, and all the various TextBoxes in that dialog which need this have their Validating event pointing to the same method. So it's not like I've got 20 of these in a given source file (one for each TextBox) or anything; there's only one for the whole dialog class.
Problem is, the whole set of these exists in every source file where I need them. That's one set for the main window and more for each pop-up dialog box -- and that's too many. I understand modal dialog box classes can't communicate with each other, and making all this stuff global is elusive at best and a big "no-no" at worst.
I have successfully tried passing a reference to "FormMain" (where one copy of these routines exist) to the various dialog constructors, and then calling these validation routines with that from their own validation handlers. It works but feels awfully clunky and certainly not like the best approach.
So, how would I (or would I want to) rearrange the project and organize the code better to have only a single instance of these kinds of things? How would I wire up a global "utility" class of such methods such that I can get to it from the main form's code and from that of a bunch of pop-up modal dialog boxes as well?
I'd like to maintain just one executable with no additional .DLLs if possible (these are all one-project-per-solution, by the way), and if practical I'd like to further be able to share that common code across multiple solutions.
I think the answer will include writing new assemblies, using different namespaces (currently all my code in a given project is contained in the same namespace), and maybe separating this stuff out into its own project in the same solution file.
Is it possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以通过将代码保留在一个位置并添加指向每个解决方案中的文件的链接来跨解决方案共享代码。
要添加链接:右键单击要添加代码的项目(或文件夹),然后选择“添加现有项目”,浏览找到该文件,找到后单击按钮上的向下箭头并选择链接到。
这样,链接到该文件的项目将共享相同的代码。
顺便说一句:使用不知道如何处理这些链接的源代码控制系统时要小心。
You can share code across solutions by keeping the code in one place and adding a link to the file in each solution.
To add a link: right click the project (or folder) you want to add the code to, then select "Add existing item", browse for the file, when found click the down arrow on the button and pick Link to.
This way the projects that link to the file will share the same code.
BTW: take care when using a source control system that doesn't know how to handle these links.