【问题标题】:Switch between multiple windows在多个窗口之间切换
【发布时间】:2020-12-02 23:24:04
【问题描述】:

我们的软件系统应该支持多种变体。每个变体都应包含一个或多个 UI 组件(在本例中为 Windows 窗体)的自定义版本。

已经在VS2017中创建了一个原型,解决方案如下; ProductFoo(解决方案)

  • MainApplication(Windows 应用程序)
    • MainApplicationForm1.cs(Windows 窗体)
  • XY1(类库)
    • Form1.cs((Windows 窗体)
  • XY2(类库)
    • Form1.cs((Windows 窗体)

在这个简单的原型中,MainApplicationForm1 表单包含一个按钮,单击该按钮应在 XY1 og XY2 库中显示 Form1.cs,具体取决于选择的变体。

为了解决这个问题,我们已使用以下解决方案配置更新了解决方案管理器;

  • XY1_Debug
  • XY1_Release
  • XY2_Debug
  • XY2_Release

然后我们为 MainApplication 添加了条件编译符号。

  • 解决方案配置 XY1_Debug 和 XY1_Release 使用条件符号 XY1
  • 解决方案配置 XY2_Debug 和 XY2_Release 使用条件符号 XY2

然后我们将 MainApplication 的引用添加到 XY1 和 XY2 项目。

最后,我们在 MainApplicationForm1.cs 中添加了以下代码

public partial class MainAppForm1 : Form
{
    public MainAppForm1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    #if XY1
        XY1.Form1 form = new XY1.Form1();
        form.ShowDialog();
    #elif XY2
        XY2.Form1 f1 = new XY2.Form1();
        f1.ShowDialog();
    #else
        #error The MainApplication is missing Form1
    #endif
    }
}

此解决方案有效,但我对使用预处理器指令有所保留。代码看起来很乱,很快就会变得难以维护。这种场景的最佳做法是什么?

感谢任何意见。

【问题讨论】:

  • 您如何检查选择了哪个变体?
  • 开发人员需要选择一个反映变体的解决方案配置(XY1_Debug 或 XY2_Debug 等)。
  • 我知道。但我的问题是开发人员如何选择它?您说您需要改进代码以减少混乱,那么原始代码是什么?不知道我说得够不够抱歉。
  • 哦,等等,嘘。我的坏,我的大脑终于决定工作了!好的,所以我得到了你需要的东西。但是,除了现在怎么样。我想不出如何改进,除非通过用户交互,比如在表单中添加一个单选按钮,并且根据选择的单选按钮,该按钮将打开另一个。

标签: c# visual-studio-2017 .net-4.6.1


【解决方案1】:

您的问题非常广泛,涉及您想要拥有的项目的基本结构。

您选择的方式接近Feature toggling,只是根据构建配置完成。通常它应该是这样的:

if(features.IsOn("XY1-feature")){
    XY1.Form1 form = new XY1.Form1();
    form.ShowDialog();
}

经典的方式可以给你更多的灵活性。例如。将功能切换移动到配置将使您能够为特定部署动态切换不同的功能,但作为影响,它会增加复杂性并需要更多测试

我建议您深入了解Dependency injectionStrategy pattern

作为功能切换的替代方法,您可以使用分支。为特定项目/客户创建特定分支。这可能会给您带来合并问题,但会让您更清洁以进行特定的实施。它最适合项目之间有很多细微差别的项目

【讨论】:

  • 感谢您的 cmets。依赖注入是一个有趣的想法。
【解决方案2】:

我建议使用两个单选按钮来解决这个问题。这是一个非常简单的方法。

选择radioButton1,弹出XY1​​.Form

选择radioButton2,弹出XY2.Form

MainApplicationForm1.cs:

private void radioButton1_CheckedChanged(object sender, EventArgs e)

    {
        if (radioButton1.Checked) 
        {
            XY1.Form1 form = new XY1.Form1();
            form.Show();                
        }
        
    }
    private void radioButton2_CheckedChanged(object sender, EventArgs e)
    {
        if (radioButton2.Checked)
        {
            XY2.Form1 f1 = new XY2.Form1();
            f1.Show();               
        }
    }

【讨论】:

  • 如果您遇到其他问题,请随时与我联系。
  • 感谢您的回复。不幸的是,最终用户无法查看所有变体。它不能很好地扩展并使 UI 混乱。
  • 您可以尝试使用 form.Show() 代替 form.ShowDialog() 来解决这个问题。我已经更新了我的代码,你可以检查它是否适合你。