0

テキスト値に基づいてメソッドを呼び出すことは可能ですか?

可能であれば、「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」を変更したい。

4

5 に答える 5

4

私が考えることができる最もクリーンな方法は、次のようなコンボボックスアイテムのクラスを作成することです。

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();
于 2012-08-02T20:15:26.457 に答える
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();
}
于 2012-08-02T20:16:38.670 に答える
1

コンボボックスにはリストアイテムが含まれています。MSDNによると、通常はテキスト文字列を格納するために使用されますが、コンボボックスには何でも格納できます。したがって、問題を正しく解決する最も簡単なソリューションを選択してください。

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();
}
于 2012-08-02T20:35:34.100 に答える
0

デリゲートは関数/メソッドへのポインタなので、それを使用することをお勧めします。たとえば、デリゲートシグニチャ(パラメータとそのタイプ)を使用してメソッドへのポインタの配列を作成し、配列にインデックスを付けてメソッドを呼び出します。例:

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)},
};
于 2012-08-02T20:15:18.583 に答える
0

良い解決策(一般的に言えば、特別な場合には最善の方法ではないかもしれませんが、それを判断するには、より多くの情報が必要です)は、単なる文字列ではなく、オブジェクトをComboBoxに格納するようです。これらのオブジェクトは、ComboBoxに表示されるテキストと、呼び出すメソッドを実行する方法を提供する必要があります。

SetOutputStateこの例では、常にインスタンスのメソッドを呼び出しているように見えOutPortます(ここではクラス名を想定しています)。したがって、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

于 2012-08-02T20:18:43.697 に答える