【问题标题】:Is it possible to invoke a method based off a combobox.selecteditem.tostring() in C#?是否可以在 C# 中调用基于 combobox.selecteditem.tostring() 的方法?
【发布时间】:2012-07-31 20:51:33
【问题描述】:

是否可以调用基于文本值的方法?

如果可能,我不想使用“if”或“switch”语句。

如果是这样,我需要看什么才能做到这一点?

这只是为了尝试清理界面。

if 语句示例:

    if (cmb_Motor.SelectedItem.ToString() == "OutPortA")
             NXT_Brick.OutPortA.SetOutputState();
    else if (cmb_Motor.SelectedItem.ToString() == "OutPortB")
             NXT_Brick.OutPortB.SetOutputState();
    else if (cmb_Motor.SelectedItem.ToString() == "OutPortC")
             NXT_Brick.OutPortC.SetOutputState();

我想在“NXT_Brick”之后更改“OutPortA、B、C”。

【问题讨论】:

    标签: c# object methods invoke


    【解决方案1】:

    我能想到的最简洁的方法是为您的组合框项目创建一个类,如下所示:

    class Item
    {
      public string Name{get;set;}
      public Action Action{get;set;}
    
      public override string ToString() { return Name; }
    }
    

    然后将此类的实例添加到组合框中:

    cmbItems.Add(new Item{Name="Item1", Action=()=>{ /*action 1*/ });
    cmbItems.Add(new Item{Name="Item2", Action=()=>{ /*action 2*/ });
    cmbItems.Add(new Item{Name="Item3", Action=()=>{ /*action 3*/ });
    

    并且在您选择的项目更改事件中(或在您按下 OK 按钮时,无论何时),您将您的 SelectedItem 属性转换为 Item,然后调用其 Action 属性来运行代码。

    ((Item)cmbItems.SelectedItem).Action();
    

    【讨论】:

      【解决方案2】:

      ifswitch 语句可以隐藏在字典中,例如:

      private IDictionary<string, OutPort> ports = new Dictionary<string, OutPort>{
        {"OutPortA", NXT_Brick.OutPortA},
        {"OutPortB", NXT_Brick.OutPortB},
        {"OutPortC", NXT_Brick.OutPortC}
      }
      

      用法:

      if(ports.Contains(key))
      {
       ports[key].SetOutputState();
      }
      

      【讨论】:

      • 谢谢,我确实看了一些与反射有关的东西,但我可能走错了方向。
      【解决方案3】:

      组合框包含列表项。根据 MSDN,您可以将 ANYTHING 存储在组合框中,尽管它通常用于存储文本字符串。所以选择正确解决问题的最简单的解决方案。

      public class FiringComboItem
      {
         public string Text { get; set; }
         public Action OnClick { get; set; }
         override public ToString() { return Text; }
      }
      

      像这样将项目添加到组合中:

      myCombo.Add ( new FiringComboItem 
          { 
              Text = "About", 
              OnClick = () => new AboutDialog.ShowDialog()
          });
      

      在您的下拉处理程序中:

      private void myCombo_OnSelectedIndexChanged(object sender, EventArgs e)
      {
          (myCombo.SelectedItem As FiringComboItem).OnClick();
      }
      

      【讨论】:

        【解决方案4】:

        委托是指向函数/方法的指针,因此您可能想要使用它。例如,使用委托签名(参数及其类型)创建一个指向方法的指针数组,并通过索引该数组来调用该方法。一个例子:

        public delegate void SelectState();
        
        public class Test
        {
            SelectState[] stateMethods = new SelectState[]
            {
                new SelectState(SelectA),
                new SelectState(SelectC),
                new SelectState(SelectB),
                new SelectState(SelectB)
            };
        
            void SelectA() { /* ... */ }
            void SelectB() { /* ... */ }
            void SelectC() { /* ... */ }
        
            void DoSomething()
            {
                int index = cmb_Motor.SelectedIndex;
                // Get the method pointer.
                var method = stateMethods[index];
                // Call the method, one of the State*() methods.
                method();
            }
        }
        

        或者,如果您不想使用索引而是使用字符串,例如您的示例,您可能想要使用字典:

        Dictionary<string, SelectState> stateMethods = new Dictionary<string, SelectState>
        {
            {"OutPortA", new SelectState(SelectA)},
            {"OutPortB", new SelectState(SelectB)},
            {"OutPortC", new SelectState(SelectC)},
        };
        

        【讨论】:

          【解决方案5】:

          一个好的解决方案(一般来说 - 在您的特殊情况下可能不是最好的方法,但要判断这一点,我们需要更多信息)似乎将对象存储在 ComboBox 中,而不仅仅是字符串。这些对象应提供 ComboBox 中可见的文本以及运行您要调用的方法的方法。

          在您的示例中,您似乎总是在调用 OutPort 实例的 SetOutputState 方法(假设此处的类名),因此您的 ComboBox 项目对象可能如下所示:

          public class ComboItem
          {
              public ComboItem(string displayName, OutPort outPort)
              {
                  this.displayName = displayName;
                  this.outPort = outPort;
              }
          
              private readonly string displayName;
          
              private readonly OutPort outPort;
          
              public override string ToString()
              {
                  return displayName;
              }
          
              public OutPort OutPort {
                  get {
                      return outPort;
                  }
              }
          }
          

          请注意,ToString 方法的结果将是 ComboBox 中用户可见的字符串。

          您必须像这样填充 ComboBox:

          cmb_Motor.Items.Add(new ComboItem("OutPortA", NXT_Brick.OutPortA);
          cmb_Motor.Items.Add(new ComboItem("OutPortB", NXT_Brick.OutPortB);
          cmb_Motor.Items.Add(new ComboItem("OutPortC", NXT_Brick.OutPortC);
          

          然后您可以像这样评估所选项目:

          ComboItem selectedItem = cmb_Motor.SelectedItem as ComboItem;
          if (selectedItem != null) {
              selectedItem.OutPort.SetOutputState();
          }
          

          如果您希望对所选项目执行更多变化,请将要执行的操作也移到 ComboItem 类中:

          public class ComboItem
          {
              public ComboItem(string displayName, OutPort outPort)
              {
                  this.displayName = displayName;
                  this.outPort = outPort;
              }
          
              private readonly string displayName;
          
              private readonly OutPort outPort;
          
              protected OutPort OutPort {
                  get {
                      return outPort;
                  }
              }
          
              public override string ToString()
              {
                  return displayName;
              }
          
              public virtual void DoWork()
              {
                  outPort.SetOutputState();
              }
          }
          

          OutPort 属性现在不再需要公开;您只需在所选项目上调用DoWork。因此,评估代码可以更改为:

          ComboItem selectedItem = cmb_Motor.SelectedItem as ComboItem;
          if (selectedItem != null) {
              selectedItem.DoWork();
          }
          

          对于需要不同操作的任何事情,您现在可以从 ComboItem 派生一个新类,该类将覆盖 DoWork 方法以执行不同的操作。

          【讨论】:

            猜你喜欢
            • 2014-04-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-28
            • 2023-03-14
            • 1970-01-01
            • 2011-01-28
            相关资源
            最近更新 更多