【问题标题】:return enum value based on selection根据选择返回枚举值
【发布时间】:2012-02-14 19:40:19
【问题描述】:

我有一个枚举

public enum Operation
{
    Add = 1,
    Substract = 2,
    Multiply = 3,
    Divide = 4
}

我有四个单选按钮:加、减、乘、除。

根据选择,我想返回对应的 Enum 值。我所有的单选按钮都出现在一个组合框中。

我知道这是一件简单的事情,但很长一段时间我都无法做到。谢谢。

编辑

这就是我尝试过的......

    public Operation Operation
    {
        get
        {
            foreach (Control control in gbxOperation.Controls)
            {
                var radioButton = control as radioButton;
                if (radioButton != null && radioButton.Checked)
                {
                    if(radioButton.Text.ToLower() == "add")
                        return Operation.Add;
                    if (radioButton.Text.ToLower() == "subtract")
                        return Operation.Substract;
                    if (radioButton.Text.ToLower() == "multiply")
                        return Operation.Multiply;
                    if (radioButton.Text.ToLower() == "divide")
                        return Operation.Divide;
                }
            }
            return Operation.Add;
        }
    }

【问题讨论】:

  • Winforms?网络表格? WPF? MVC? WP7?银光?地铁?单触? MonoDroid?
  • 请显示单选按钮事件的代码。
  • 你在 UI 上使用什么 asp.net、winforms、WPF?
  • 地铁?表格? WPF?银光? ASP.NET?单触?
  • 这是作业吗?你试过什么?

标签: c# winforms c#-4.0 enums


【解决方案1】:

你的问题不是很清楚,但是如果你有一个像"Add"这样的字符串,并且你想将它转换为Operation,你可以使用Enum.Parse()。比如:

Operation op = (Operation)Enum.Parse(typeof(Operation), s);

但可能更好的选择是将单选按钮与枚举值直接关联,而不是通过按钮的文本。具体如何操作取决于您使用的是哪种 UI 库。

【讨论】:

    【解决方案2】:

    您可以为此目的使用 RadioButton 的 Tag 属性:

    在InitializeComponent()之后的构造函数中:

    addButton.Tag = Operation.Add;
    subtractButton.Tag = Operation.Subtract;
    addButton.Tag = Operation.Multiply;
    addButton.Tag = Operation.Divide;
    
    public Operation Operation         
    {             
      get             
      {
        RadioButton checkedButton = gbxOperation.Controls.OfType<RadioButton>().
                                                 Where(button => button.Checked).First();
        return (Operation)(checkedButton.Tag);
      }
    }   
    

    【讨论】:

      【解决方案3】:

      我会选择将字符串 .Tag 添加到 RadioButton 控件与 Enum 中的名称的简单组合,并在按钮更改时解析事件中的字符串:

      public Operation Operation { get; private set; }
      
      private void rb_CheckedChanged(object sender, EventArgs e)
      {
          var rb = sender as RadioButton;
          if (rb.Checked)
          {
              this.Operation = (Operation)Enum.Parse(typeof(Operation), rb.Tag as string);
              ...
          }
      }
      

      【讨论】:

      • 为什么不把枚举直接放到Tag中呢?
      • @svick - 尝试过,当我更改 .Designer.cs 文件时 VS 设计器抱怨。将 Tag 分配给字符串时,它更喜欢它。当然,我可以覆盖 OnLoad() 并将其设置在那里,但为简单起见,这样做效果最好。
      • 您不能直接通过设计器将枚举添加到 Tag 属性,您应该避免编辑自动生成的 InitializeComponent 方法。我之前用两个样本发布了这个问题的答案。其中,一个示例演示了如何在构造函数中分配 Tag 属性。我更喜欢在构造函数中这样做,因为它比尝试搜索 InitializeComponent 更容易维护。
      【解决方案4】:

      我假设您使用的是 Windows 窗体。在下面的示例中,您可以使用多种方法中的两种:

      1. 使用用于自定义用户数据的 Tag 属性。然后,您可以将 Tag 值转换为已选中的单选按钮的枚举。

      2. 或者,只需在单选按钮和枚举之间创建一个字典。您可以使用单选按钮作为键,使用操作枚举作为您的值。

      问候。

      public class MyForm : Form
      {
          public MyForm()
          {
              InitializeComponent();
      
      
              // Method 1) The Tag property on any control can be user as user data
              radioButton1.Tag = Operation.Add;
              radioButton2.Tag = Operation.Subtract;
              radioButton3.Tag = Operation.Multiply;
              radioButton4.Tag = Operation.Divide;
      
              // Method 2) Use a Dictionary
              radioButtonToOperation = new Dictionary<RadioButton, Operation> 
                  {
                      { radioButton1, Operation.Add },
                      { radioButton2, Operation.Subtract },
                      { radioButton3, Operation.Multiply },
                      { radioButton4, Operation.Divide },
                  };
          }
      
          // Fields
          GroupBox groupBox1;
          RadioButton radioButton1;
          RadioButton radioButton2;
          RadioButton radioButton3;
          RadioButton radioButton4;
          Dictionary<RadioButton, Operation> radioButtonToOperation;
      
          private void InitializeComponent()
          {   
              groupBox1 = new GroupBox();
              radioButton1 = new RadioButton();
              radioButton2 = new RadioButton();
              radioButton3 = new RadioButton();
              radioButton4 = new RadioButton();
      
              groupBox1.Text = "Operations";
              groupBox1.Dock = DockStyle.Fill;
      
              radioButton1.Text = "Add";
              radioButton1.Dock = DockStyle.Top;
              radioButton1.CheckedChanged += radioButtons_CheckedChanged;
      
              radioButton2.Text = "Subtract";
              radioButton2.Dock = DockStyle.Top;
              radioButton2.CheckedChanged += radioButtons_CheckedChanged;
      
              radioButton3.Text = "Multiply";
              radioButton3.Dock = DockStyle.Top;
              radioButton3.CheckedChanged += radioButtons_CheckedChanged;
      
              radioButton4.Text = "Divide";
              radioButton4.Dock = DockStyle.Top;
              radioButton4.CheckedChanged += radioButtons_CheckedChanged;
      
              groupBox1.Controls.Add(radioButton4);
              groupBox1.Controls.Add(radioButton3);
              groupBox1.Controls.Add(radioButton2);
              groupBox1.Controls.Add(radioButton1);
              Controls.Add(groupBox1);
          }
      
          void radioButtons_CheckedChanged(object sender, EventArgs e)
          {
              RadioButton radioButton = sender as RadioButton;
              if (radioButton == null) return;  // Not a radio button
              if (!radioButton.Checked) return; // Radio button isn't checked
      
              // Method 1) Get the Operation from the Tag property
              Operation? operationFromTag = GetOperationFromTag(radioButton);
              Console.WriteLine("From Tag: " + (operationFromTag == null ? "(none)" : operationFromTag.ToString() ));
      
              // OR Method 2) Get the Operation from the Dictionary
              Operation? operationFromDictionary = GetOperationUsingDictionary(radioButton);
              Console.WriteLine("From Dictionary: " + (operationFromDictionary == null ? "(none)" : operationFromDictionary.ToString()) );
          }
      
          private Operation? GetOperationFromTag(RadioButton radioButton)
          {
              if (radioButton == null) return null;
      
              if (radioButton.Tag is Operation)
              {
                  Operation operationFromTag = (Operation)radioButton.Tag;
                  return operationFromTag;
              }
      
              return null;
          }
      
      
          private Operation? GetOperationUsingDictionary(RadioButton radioButton)
          {
              if (radioButton == null) return null;
      
              Operation operationFromDictionary;
              return
                  radioButtonToOperation.TryGetValue(radioButton, out operationFromDictionary)
                  ? operationFromDictionary
                  : (Operation?)null;
          }
      
          public Operation? SelectedOperation
          {
              get
              {
                  // You must include System.Linq in your using block at the top of the file for the following
                  // extension methods to be picked up by the compiler:
                  // * Enumerable.OfType<T> is an extension method on IEnumerable. 
                  // * Enumerable.SingleOrDefault<T> is an extension method on IEnumerable<T>
      
                  RadioButton selectedRadioButton = 
                      groupBox1.Controls                                                      // Go through each of the groupbox child controls
                          .OfType<RadioButton>()                                          // Need to convert Controls, which is IEnumerable, to IEnumerable<Control>
                          .Where(radioButton => radioButton.Checked)  // Filter through only the checked radio buttons
                          .SingleOrDefault();                         // Get the single result, or none. (Exception if there are more than one result)
      
                  return GetOperationUsingDictionary(selectedRadioButton);
              }
          }       
      }
      
      public enum Operation
      {
              Add = 1,
              Subtract = 2,
              Multiply = 3,
              Divide = 4
      }
      

      【讨论】:

      • -1 太长且令人费解。你真的需要可为空的类型和辅助函数吗?
      • 最初,没有选择单选按钮,因此可空类型可用于指示“未选择值”。是的,示例有点长,但它确实可以轻松复制和粘贴以供自己测试。至于辅助函数,它使代码可重用、可读且更易于维护,因为您不会将单个方法与太多非特定功能混为一谈。虽然第一段的解释很简短,但非常直接。
      猜你喜欢
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多