1

私はwinformsとそのコントロールで少し遊んでいて、カスタムメイドのボタンクリックを行う方法を発見しました。ただし、問題があります。要素のリストをループするループがあり、条件が表示された場合は、グリッドビューをポップアップするボタンを作成しています。

public void draw(ref Panel inputPanel) //draws the eventline
    {
        int stepCounter = 0;
        for (int i = 0; i < DaysList.Count-1; i++)
        {
            Button b1;
            if (DaysList[i].Elements.Count > max)
            {
                b1 = new Button(); //Create the box
                b1.Width = 120;
                b1.Height = 40; //Set width and height
                b1.Location = new Point(stepCounter + 35, 70); //Location
                inputPanel.Controls.Add(b1); //
                b1.Text = "Check event date in grid";
                b1.Show();
                b1.BringToFront();
                b1.Click += new EventHandler((sender, e) => btn_Click(sender, e, DaysList[i].Elements));
                stepCounter += 200;
            }
         }
     } 

これが、条件が表示されたときのボタンとクリック イベントを作成する私の方法でした。イベント ハンドラに渡される関数は次のようになります。

public void btn_Click(object sender, EventArgs e, List<EventElement> inputElems)
    {
        Button button = sender as Button;
        DataGridForm window = new DataGridForm(inputElems);
        window.Show();
    }

public class EventElement
{
     public EventElement()
     {
     }
     public int Count{get;set;}
     public string Date{get;set;}
}

イベントのクリック部分は問題ありませんが、生成されたボタンをクリックすると、グリッドビューに間違ったデータが表示されます。例として:ループは私のために4つのボタンを作成し、それらはフォーム上の直線上に表示されます. しかし、ボタンの 1 つをクリックするたびに、どのボタンでもかまいません。ボタンは常に、最後に生成されたボタンのデータを返します。より明確な例: リスト inputElems があるとしましょう:
inputElems[0].Count -> 2644
inputElems[1].Count -> 2131
inputElems[2].Count -> 8467
inputElems[3].Count - > 5462
2 番目のボタンをクリックすると、2 番目のボタンのパラメーター リストへの入力には値 (sender、e、2131) が必要ですよね? しかし、何らかの理由で、2番目に作成されたボタンを呼び出しても、最後の引数はリストの4番目の要素と同じになります。

最後に追加された button_click をボタンのイベントハンドラーに常に呼び出すことと関係があると考えました。そうであれば、EventHandler から別のクリックを呼び出すにはどうすればよいですか?

4

2 に答える 2

1

問題は、forループが範囲外であるため、探しているデータを提供できないことです。より直接的なアプローチは、次のようなものです。

public void draw(ref Panel inputPanel) //draws the eventline
{
    int stepCounter = 0;
    for (int i = 0; i < DaysList.Count-1; i++)
    {
        Button b1;
        if (DaysList[i].Elements.Count > max)
        {
            b1 = new Button(); //Create the box
            b1.Width = 120;
            b1.Height = 40; //Set width and height
            b1.Location = new Point(stepCounter + 35, 70); //Location
            inputPanel.Controls.Add(b1); //
            b1.Text = "Check event date in grid";
            b1.Show();
            b1.BringToFront();
            b1.Tag = DaysList[i].Elements;
            b1.Click += btn_Click;
            stepCounter += 200;
        }
     }
 } 

で、次の操作をbtn_Click行います。

public void btn_Click(object sender, EventArgs e)
{
    Button button = sender as Button;
    int inputElems = (List<EventElement>)button.Tag;
    DataGridForm window = new DataGridForm(inputElems);
    window.Show();
}
于 2013-07-01T14:24:51.653 に答える
1

EventHandler で inputElems を渡す代わりに、Tag を使用できます。

使用例:

b1.Tag=i;

次に、クリック イベント ハンドラーで次のようにします。

public void btn_Click(object sender, EventArgs e)
    {
        Button button = sender as Button;
        DataGridForm window = new DataGridForm(DaysList[int.Parse(button.Tag.ToString())].Elements);
        window.Show();
    }
于 2013-07-01T14:22:49.230 に答える