2017-10-25 9 views
0

私はここで少し問題があります。C# - 動的なデータ入力を伴う動的ボタン

私は可変データを持つ動的clickeventsを作成しようとしています。

for(int i = 0; i < data.Devices.Length; i++) 
{ 
    Button _button = new Button(); 
    _button.Size = new Size(100, 15); 
    _button.Text = data.Devices[i].Alias; 
    _button.Name = "textbox" + i.ToString(); 
    _button.Location = new Point(x,y); 
    x += 110; 

    if(x > 1850) 
    { 
     y += 50; 
     x = 10; 
    } 

    if (data.Devices[i].OnlineState == "Online") 
    { 
     _button.BackColor = Color.Green; 
    } 
    else 
    { 
     _button.BackColor = Color.Red; 
    } 

    _button.Click += (Sender, args) => 
    { 
     MessageBox.Show(data.Devices[i].Alias); 
    }; 

    Controls.Add(_button); 
} 

ここでの考え方は、リストの長さは、(これらのオブジェクトのリストと位置が異なる場合)に行われるまで、私は、ボタンを作成しますということです。

私が探しているのは、たくさんのボタンを作ることです。ボタンをクリックすると、そのオブジェクトにいくつかの統計情報が添付された別の画面が開きます。

データはさまざまなので、各シナリオをハードコードする方法はありませんが、代わりに私はAndroidでできることと同じことを探しています。下記を参照してください。

for (int i = 1; i <= 20; i++) { 
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, 
     LinearLayout.LayoutParams.WRAP_CONTENT); 

    Button btn = new Button(this); 
    btn.setId(i); 
    final int id_ = btn.getId(); 
    btn.setText("button " + id_); 
    btn.setBackgroundColor(Color.rgb(70, 80, 90)); 
    linear.addView(btn, params); 
    btn1 = ((Button) findViewById(id_)); 

    btn1.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      Toast.makeText(view.getContext(), "Button clicked index = " + id_, Toast.LENGTH_SHORT).show(); 
    } 
}); 

私はこれを達成する方法はありますか?

親切にしてください。

+0

遭遇している問題は何ですか? – PeteGO

答えて

0

ボタンを作成して画面に配置することから始めます。

for (int i = 0; i < data.Devices.Length; i++){ 
Button _button = new Button(); 
_button.Size = new System.Drawing.Size(100, 55); 
_button.Text = data.Devices[i].Alias; 
_button.Name = "dynamicButton"; 
_button.FlatStyle = FlatStyle.Flat; 
_button.Tag = data.Devices[i].Alias + "|" + 
       data.Devices[i].DeviceId + "|" + 
       data.Devices[i].LastSeen + "|" + 
       data.Devices[i].OnlineState + "|" + 
       data.Devices[i].Description + "|" + 
       data.Devices[i].RemotecontrolId; 

_button.Location = new System.Drawing.Point(x, y); 
x += 110; 
if (x > 1850) 
{ 
    y += 60; 
    x = 30; 
} 
_button.Click += new EventHandler(bt_click); 
Controls.Add(_button); 
} 

そして、onclickイベントを使用。

protected void bt_click(object sender, EventArgs e) 
    { 
     Button btn = sender as Button; 
     String[] information = btn.Tag.ToString().Split('|'); 
     String present = "Namn: " + information[0] 
         + "\nDeviceID: " + information[1] 
         + "\nSenast uppe: " + information[2] 
         + "\nStatus: " + information[3] 
         + "\nEmail: " + information[4] 
         + "\nTW-ID: " + information[5]; 
     MessageBox.Show(present); 
     //DO THE THINGS WITH THE INFORMATION     
    } 

すべてをアンロードし、最終的にデバイスのステータスを更新します。私はそれがそれらをすべて削除しませんbeacuse、ループそのことを数回に持っているが、その代わりに、いくつかのパターンでそれらを削除するいくつかの理由

for (int i = 0; i < 10; i++) 
     { 
      foreach (Control item in Controls.OfType<Control>()) 
      { 
       if (item.Name == "dynamicButton") 
       { 
        Controls.Remove(item);       
       } 
      } 
     } 

。 (1回おきにしかかかりません)

いいえ対策のために10回ループしました。

これは私がやりたいことであり、新しいデバイスが自動的に追加され、削除されたデバイスはすぐに消えてしまいます。

+0

それを聞いてうれしいです。個人的には、文字列の操作を避け、 '_button.Tag = data.Devices [i]'で行って、イベントハンドラ 'Device d =(Device)((Button)sender).Tag; – PeteGO

+0

私はループの問題は、あなたが変更しているコレクションを反復処理しているということです。 'Controls.ToList()。RemoveAll(x => x.Name == "dynamicButton"); ' – PeteGO

2

あなたが経験している問題はclosuresに関するものだと思います。

例では、各ループの繰り返しを変更する変数iを参照するデリゲートをイベントハンドラに追加しています。したがって、イベントハンドラが実際に実行されたとき(ボタンがクリックされたとき)iは範囲外です。あなたのケースでは

private void Form1_Shown(object sender, EventArgs e) 
{ 
    var items = new[] { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" }; 

    for (int i = 0; i < items.Length; i++) 
    { 
     var btn = new Button 
     { 
      Text = $"Button {i + 1}", 
      Tag = items[i] 
     }; 

     btn.Click += (object obj, EventArgs args) 
      => 
      { 
       MessageBox.Show($"Hello. {((Button)obj).Tag}"); 
      }; 

     flowLayoutPanel1.Controls.Add(btn); 
    } 
} 

- ボタンのタグがdata.Devices[i]に設定することができます - 言い換えれば、それはそれはオブジェクトにすることができ、文字列である必要はありません。

あなたはこのような何かを行うことができます。

+0

こんにちはPeteGo、私は何かを描くことができました。コードは以下に掲載されています。 – AlWooz

関連する問題