3

行を持つ TableLayoutPanel (tlp) があります。ボタンで手動で行を追加します。最後の行の下に作成したすべての行には、tlp から行を削除するボタンがあります。コードは次のとおりです。

    private void btnTSatirEkle_Click(object sender, EventArgs e)
    {
        tlpTDersRows = tlpTDers.RowCount;

        tlpTDers.RowCount++;

        DateTimePicker dtp = new DateTimePicker();
        dtp.Name = "dtpTR" + (tlpTDersRows).ToString();
        DateTimePicker dtp2 = (DateTimePicker)tlpTDers.Controls["dtpTR" + (tlpTDersRows - 1).ToString()];
        dtp.Value = dtp2.Value.AddDays(1);
        dtp.Dock = DockStyle.Fill;
        tlpTDers.Controls.Add(dtp, 0, tlpTDersRows);

        ComboBox comb = new ComboBox();
        comb.Name = "cbxTR" + (tlpTDersRows).ToString();
        comb.Dock = DockStyle.Fill;
        comb.Items.AddRange(devamDur);
        tlpTDers.Controls.Add(comb, 1, tlpTDersRows);

        TextBox txtr = new TextBox();
        txtr.Name = "txtTR" + (tlpTDersRows).ToString();
        txtr.Dock = DockStyle.Fill;
        txtr.Multiline = true;
        tlpTDers.Controls.Add(txtr, 2, tlpTDersRows);

        oldX = btnTSatirEkle.Location.X;
        oldY = btnTSatirEkle.Location.Y;

        Button buttonNew = new Button();
        buttonNew.Name = "btnDelTR" + (tlpTDersRows - 1).ToString();
        buttonNew.Text = "-";
        buttonNew.Location = new Point(oldX, oldY);
        buttonNew.Size = btnTSatirEkle.Size;
        this.Controls.Add(buttonNew);
        buttonNew.Click += new EventHandler(SatirSil);  //I get error here, even I write SatirSil(sender, e, tlpTDersRows - 1)..

        btnTSatirEkle.Location = new Point(644, tlpTDers.Controls["dtpTR" + tlpTDersRows.ToString()].Location.Y + 12);

        tlpTDersRows++;
    }

    private void SatirSil(object sender, EventArgs e, int rowNo)
    {
       //codes
    }

行番号をパラメータとしてSatirSilメソッドに送信したい(buttonNew_Clickイベントをクリックすると呼び出される)。

何か案は?

4

6 に答える 6

2

変化する:

buttonNew.Click += new EventHandler(SatirSil);

buttonNew.Click += new EventHandler((snd, ev)=>SatirSil(snd,ev,rowno));

または独自の変数(つまりtlpTDersRows)を使用すると、次のようになります。

buttonNew.Click += new EventHandler((snd, ev)=>SatirSil(snd,ev,tlpTDersRows-1));
于 2013-06-28T12:47:43.083 に答える
2

イベントは次のButton.Clickように定義されます。

public event EventHandler Click

EventHandlerによって定義される場所

public delegate void EventHandler(Object sender, EventArgs e);

これは、メソッドがイベントのハンドラーとして割り当て可能であるためには、デリゲートによって定義された正確なシグネチャを持っている必要があることを意味objectEventArgsますvoidSatirSilメソッドの署名

void SatirSil(object sender, EventArgs e, int rowNo)

追加の整数パラメーターがあるため、一致しません。他の回答で述べたように、この問題には 2 つの一般的な解決策があります。

  • それ自体はほとんど役に立たないsenderため、何らかの方法で追加のパラメーターをパラメーターに埋め込みます。EventArgsほとんどの場合、sender パラメーターは実際にはControlオブジェクトであるため、Control.Tagプロパティを使用して送信者に関する追加データを格納するのが一般的です。このデータは、ハンドラーによって取り出され、必要に応じて使用されます。それは次のようになります。

    Button buttonNew = new Button();
    ...
    buttonNew.Tag = (tlpTDersRows - 1);
    buttonNew.Click = SatirSil;
    ....
    void SatirSil(object sender, EventArgs e)
    {
       int rowNumber = (int)(sender as Control).Tag;
       //rest of code
    }
    
  • どういうわけか、行番号が「ハードコーディング」される特殊なバージョンのハンドラーを作成します。C# 3.0 以降では、インラインの「メソッド」を生成するラムダ構文を使用して、これを比較的簡単に実現できます。

    EventHandler handler = (sender, e) => {...code here ...}
    

    を使用して、イベントにアタッチできる「ハンドラー」と呼ばれるデリゲート インスタンスを作成するコードです。

    someButton.Click += handler;
    

    または、次を使用して呼び出すこともできます

    handler(senderValue, eValue); 
    

    「...code here...」ブロックは、宣言を記述した元のメソッドにまだ含まれているため、メソッドにアクセスできるものはすべて、ラムダ式の本体にアクセスできることに注意してください。次のようなコードを使用して、ボタンごとに個別のハンドラーを作成できることを知っています。

    Button buttonNew = new Button();
    ...
    buttonNew.Click = (_, __) => SatirSil(rowNumber);
    //if you do not care about parameters, 
    //it's customary to use _, __,  etc for the names
    //instead of the more verbose
    //buttonNew.Click = (sender, e) => SatirSil(rowNumber);
    ....
    void SatirSil(int rowNumber)
    {
       //actual implementation
    }
    

個人的には 2 番目のオプションを好みます。これは、ボタンの作成と接続に関係するコードが、実際の作業を行うコードからきちんと分離されているためです。たとえばSatirSil、コードの別の部分でメソッドが必要な場合、呼び出しはそれぞれ次のようになります。

Control dummy = new Control();
dummy.Tag = myRowNumber;
SatirSil(dummy, null);

SatirSil(myRowNumber);
于 2013-06-28T13:13:29.707 に答える
1

ボタンはsenderイベントの です。したがってTag、ボタンのプロパティに行番号を保存すると、次のようになります。

buttonNew.Tag = tlpTDersRows;

次に、次のようなことができます。

private void SatirSil(object sender, EventArgs e)
{
    Button button = (Button)sender;
    int rowNo = (int)button.Tag;
    // ... delete row here.
}
于 2013-06-28T12:47:02.720 に答える
0

どうですか:

Button buttonNew = new Button();
buttonNew.Name = "btnDelTR" + (tlpTDersRows - 1).ToString();
buttonNew.Text = "-";
buttonNew.Location = new Point(oldX, oldY);
buttonNew.Size = btnTSatirEkle.Size;
this.Controls.Add(buttonNew);
buttonNew.Tag = tlpTDersRows - 1;
buttonNew.Click += SatirSil;

private void SatirSil(object sender, EventArgs e)
{
   //codes
   var btn = (Button)sender;
   var row = (int)btn.Tag;

}
于 2013-06-28T12:46:55.760 に答える
0

既に定義されているボタン クリック イベントのデリゲート シグネチャを変更する方法はありません。やろうとしていることをすると、コンパイルエラーが発生します。他の方法で達成できる方法は、ボタン名の作成中に行番号を追加して、イベントハンドラーで送信者オブジェクトをボタンにキャストし、名前を取得してそこから行番号を抽出できるようにすることです。

    buttonNew.Name = "btnDelTR_" + rowNumber

    private void SatirSil(object sender, EventArgs e, int rowNo)
    {
             int rowNo =   //split the string to get the number.
    }
于 2013-06-28T12:51:09.480 に答える