【问题标题】:C# Winforms - Trouble with IF statementsC# Winforms - IF 语句的问题
【发布时间】:2018-11-06 01:10:34
【问题描述】:

这就是我想要做的。我有一个带有多个复选框的表单。用户将选中其中的 1 个或 2 个或 12 个,然后单击一个按钮,然后会发生几件事,具体取决于选中的复选框。

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox1.Checked == true)
        {
            checkBox1.Tag = "IP";
            Console.WriteLine(checkBox1.Tag);
        }
        else
        {
            checkBox1.Tag = null;
        }
    }
    private void CheckBox2_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox2.Checked == true)
        {
            checkBox2.Tag = "PR";
            Console.WriteLine(checkBox2.Tag);
        }
        else
        {
            checkBox2.Tag = null;

        }
    }

所以这只是我在此表单上的 24 个复选框中的 2 个的代码示例。一旦用户单击按钮,表单将使用 checkboxX.Tag 变量保存文件:

        private void button2_Click(object sender, EventArgs e)
    {

        if (string.IsNullOrWhiteSpace(myFile) &
            string.IsNullOrWhiteSpace(selectDate) &
            string.IsNullOrWhiteSpace(selectDept))
        {
            MessageBox.Show("Well, that didn't work. Check your info and try again!");
            return;
        }
        else File.Exists(myFile);
        {
            MessageBox.Show("Document(s) added! " + selectDept + selectWorker +
              " for " + dateTime.Year + "-" + dateTime.Month + "-" + dateTime.Day);
            MessageBox.Show("To add more docs, re-open this program");
            if (checkBox1.Checked)
            {
                string finalName = @"C:\testing\" + selectDept + selectWorker + @"\" + 
                  checkBox1.Tag + dateTime.Year + dateTime.Month + dateTime.Day + ".pdf";
                textBox2.Text = finalName;
                File.Copy(myFile, finalName, true);
            }
            if (checkBox2.Checked)
            {
                string finalName = @"C:\testing\" + selectDept + selectWorker + @"\" + 
                  checkBox2.Tag + dateTime.Year + dateTime.Month + dateTime.Day + ".pdf";
                textBox2.Text = finalName;
                File.Copy(myFile, finalName, true);
            }

因此,就目前而言,它适用于第一个且仅适用于第一个复选框。就像,文件将按照预期的方式复制和保存,但不是有 5 个相同的文件名为“IP20181012”、“PR20181012”、“FS20181012”等,我最终得到一个名为“IP20181012”的文件,然后另一个文件刚刚命名为“20181012”,这让我相信 checkBox2.Tag 变量从未设置过。我试过使用一个单独的变量(除了内置的 checkBox1.Tag 之一),并且发生了完全相同的问题。似乎只有 checkBox1.Tag 会正确设置,而其他 checkBoxX.Tag 变量都保持为空。即使我声明了单独的变量,然后尝试在复选框中设置它们,无论我做什么,都只会设置 checkBox1 的变量。

另外,这是使用 if 语句的好方法吗?我不需要它们嵌套。我可以把它们排成一行,这样点击按钮就会遍历它下面的所有 if 语句吗?

【问题讨论】:

  • console.writeline(checkBox2.Tag) 是否向控制台输出任何内容?
  • 不,它没有。但是 checkBox1.Tag 可以。就是这么奇怪。
  • CheckBox2 事件是否已连接?调试代码时会发生什么?
  • 为什么要在选中的事件中设置.Tag?还有其他东西可以将.Tag 设置为其他东西吗?为什么它不仅仅是一个编译时常量?
  • 是否需要根据用户点击复选框来动态设置Tag属性?换句话说,您是否可以在表单设计器中为每个复选框设置标签(例如,CheckBox1 具有标签属性“IP”,CheckBox2 具有标签属性“RP”等...)。除非 Tag 对于表单上的其他功能需要为空?

标签: c# if-statement


【解决方案1】:

按钮的单击处理程序中的一堆 if 语句是一个很好的方法。而且您甚至不再需要使用 Tag 属性或处理复选框选中的事件,因为无论如何您都在检查选中的属性。

    if (checkBox1.Checked)
    {
        string finalName = @"C:\testing\" + selectDept + selectWorker + @"\IP"
            + dateTime.Year + dateTime.Month + dateTime.Day + ".pdf";
        textBox2.Text = finalName;
        File.Copy(myFile, finalName, true);
    }
    if (checkBox2.Checked)
    {
        string finalName = @"C:\testing\" + selectDept + selectWorker + @"\PR"
          + dateTime.Year + dateTime.Month + dateTime.Day + ".pdf";
        textBox2.Text = finalName;
        File.Copy(myFile, finalName, true);
    }

【讨论】:

  • 我觉得自己像个笨蛋。这是最明显和最简单的答案,我是如此沉迷于设置很酷/花哨的变量,以至于我什至没有想到要这样做。
  • 如果你要做这样的事情,尽量减少所有重复的代码。每当您复制/粘贴那么多代码时,都会产生代码气味。看看我的答案(其中只有一个 if 块),了解一些关于合理化事情的想法。
【解决方案2】:

编写更简洁的代码会让事情变得更容易。一些建议:

  1. 不要直接使用您的复选框,而是创建一个类(“CheckBoxConfigs.cs”,它将具有关于复选框功能的布尔/字符串标志(您的代码将更易于阅读/维护);

  2. 使所有复选框使用相同的处理程序(相同的“事件”函数),您可以在其中设置“CheckBoxConfigs.cs”标志(而不是使用“标记”属性,您将拥有一个具有角色的类处理标志)而不是为 24 个 CheckBox_CheckedChanged 函数创建代码;

【讨论】:

  • 首先,在 WinForms 设计器中设置每个复选框的Tag 属性。如果您不需要通过Console.WriteLine 输出某些内容,那么您甚至不需要单个CheckChanged 事件处理程序。您需要做的就是使用或不使用基于CheckedProperty 的预配置Tag 属性
  • 我想这样做,但我想我需要更多地阅读课程。我有点理解如何使用它们。我在想一个数组在这里也可能有用吗?由于每个事件都是相同的,除了将由复选框确定的几个变量。
  • @Flydog57 当我删除代码中的 CheckChanged 处理程序时,Form1.Designer.cs 中出现错误。
  • 在代码中删除而不在属性窗口中设置通常会出现此错误。可能最好的方法是清理属性窗口中的处理程序,然后手动设置。检查stackoverflow.com/questions/803242/…
  • 是的,当您设置处理程序时,设计人员在 .designer.cs 文件中编写代码以进行连接,并在常规 .cs 文件中编写处理程序的外壳(例如你来修改)。如果仅删除 .cs 文件中的处理程序,则设计器文件中的代码将引用不再存在的函数。您可以作弊并(小心地)删除执行连线的行(someControl.CheckChanged += new System.EventHandler(this.someControl_CheckChanged))。更好的方法是进入设计器的事件视图并从那里删除处理程序。
【解决方案3】:

您是如何为这些复选框创建事件处理程序的?

您是否双击了每个复选框?

或者您是否双击一个,创建事件处理程序,然后为其他每个复制并更改该事件处理程序?

您看不到的是,在代码隐藏文件 (MyForm.Designer.cs) 中,每个事件处理程序都有一行如下所示:

this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);

那是实际连接事件的线路。如果没有该行,您的复选框实际上不会响应任何内容。

如果您从 VB6 或 VBA 开始,那会有点令人困惑,因为在这些语言中,只需创建一个具有正确名称的方法就会神奇地导致这种连接发生。但在 C#(和 VB .NET)中它是显式的,即使它可能隐藏在 Designer 文件中。

但您也可以自己添加这些行。这是我一直这样做的方式,所以设计师没有隐藏任何东西。在表单的构造函数中,您可以这样键入它们:

public MyForm()
{
    checkBox1.Checked += checkBox1_Checked;
    checkBox2.Checked += checkBox2_Checked;
    [etc.]
}

【讨论】:

  • 我认为这可能是我做错了,但是当我输入' checkBox2.Checked += checkBox2_Checked;'我收到一条错误消息,提示“当前上下文中不存在名称‘checkBox2_Checked’”。当我尝试在 Form1.Designer.cs 端手动输入时出现类似错误。
  • 在上面的代码中,您将其大写:CheckBox2_CheckedChanged。 C# 区分大小写。尝试更改连接线或方法名称。
  • @TnD_Guy 你也可以考虑在 codereview.stackexchange.com 上发布代码,人们可以帮助你找到更有效的方法(= 更少的代码)来做你正在做的事情。
  • 我喜欢代码审查的想法。万一你看不出来,我对编码很陌生,我正在研究 YouTube 教程和谷歌搜索。像这样的网站很棒,因为大多数问题已经被别人问过了!谢谢你的帮助:)
  • @TnD_Guy,如果任何答案有帮助,您可以通过投票来表明这一点。如果它解决了您的问题,您可以接受答案(复选框)。这有助于其他可能遇到相同问题并正在寻找解决方案的访问者。
【解决方案4】:

首先将设计器中每个复选框的 Tag 属性设置为您想要的字符串。然后,摆脱 CheckChanged 处理程序。最后,在你的按钮处理程序中做这样的事情(我做了明显的修改(比如我不叫File.Copy)):

 private void button2_Click(object sender, EventArgs e)
 {
     var selectDept = "MyDept";
     var selectWork = "MyWork";
     var myFile = @"c:\somefolder\somefile.ext";
     var dateTime = DateTime.Now;

     var formattedDate1 = dateTime.ToString("yyyy-MM-dd");
     var formattedDate2 = dateTime.ToString("yyyyMMdd");
     MessageBox.Show($"Document(s) added {selectDept}{selectWork} for {formattedDate1}");
     var checkboxes = new[]
     {
         checkBox1,
         checkBox2,
         checkBox3,
         //you get the idea
     };
     foreach (var checkbox in checkboxes)
     {
         if (checkbox.Checked)
         {
             var finalName = $@"C:\testing\{selectDept}{selectWork}\{checkbox.Tag}{formattedDate2}.pdf";
             textBox1.Text = finalName;      //no sure what this is for
             Debug.WriteLine($"MyFile: [{myFile}], Final Name: [{finalName}]");
         }
     }
 }

如果我选中第一个和第三个复选框(其Tag 属性是“CK1”和“CK2”,我的输出中会出现以下内容:

MyFile: [c:\somefolder\somefile.ext], Final Name: [C:\testing\MyDeptMyWork\CK120181105.pdf]
MyFile: [c:\somefolder\somefile.ext], Final Name: [C:\testing\MyDeptMyWork\CK320181105.pdf]

我认为这非常接近您想要的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2015-09-16
    • 2021-05-15
    • 2023-03-19
    相关资源
    最近更新 更多