2015-06-21 124 views
2

下面的程序實際上並不是我的項目,但它可以讓我更容易理解我以後在真實程序中想要的內容。如何處理具有相同父項的不同事件處理程序?

這裏一個.gif查看當前功能:

我想要什麼? 我想添加一個標籤總積分。其中包括複選框和文本框的點,這應該也是實時計算。對於每個組(面板)

問題在哪裏? 我不知道如何管理這個,因爲我正在處理兩個不同的事件處理程序。

這裏是源:

namespace Test1 
{ 
    public partial class Form1 : Form 
    { 
     int chkBoxX = 10; 
     int chkBoxY = 30; 
     int txtBoxX = 10; 
     int txtBoxY = 50; 
     int panelX = 0; 
     int panelY = 0; 


     public Form1() 
     { 
      InitializeComponent(); 

      for (int k = 1; k <= 3; k++) 
      { 

       Panel panel = new Panel(); 
       panel.Width = 550; 
       panel.Height = 100; 
       panel.Location = new Point(panelX, panelY); 
       panel.BackColor = Color.RoyalBlue; 


       panelY += 110; 

       this.Controls.Add(panel); 
        AddElements(panel); 

      }           

     } 

     void AddElements(Panel panel) { 

      Label labelChkBoxPoints = new Label(); 
      labelChkBoxPoints.Name = "labelChkBoxPoints"; 
      labelChkBoxPoints.Location = new Point(400, 30); 
      labelChkBoxPoints.AutoSize = true; 
      labelChkBoxPoints.BackColor = Color.White; 
      labelChkBoxPoints.Font = new Font(labelChkBoxPoints.Font.FontFamily, 12, FontStyle.Bold); 

      panel.Controls.Add(labelChkBoxPoints); 

      Label labelTxtBoxPoints = new Label(); 
      labelTxtBoxPoints.Name = "labelTxtBoxPoints"; 
      labelTxtBoxPoints.Location = new Point(400, 50); 
      labelTxtBoxPoints.AutoSize = true; 
      labelTxtBoxPoints.BackColor = Color.White; 
      labelTxtBoxPoints.Font = new Font(labelChkBoxPoints.Font.FontFamily, 12, FontStyle.Bold); 

      panel.Controls.Add(labelTxtBoxPoints); 

      Label labeltotalPoints = new Label(); 
      labeltotalPoints.Location = new Point(430, 40); 
      labeltotalPoints.Font = new Font(labeltotalPoints.Font.FontFamily, 14, FontStyle.Bold); 
     //  labeltotalPoints.Text = "10XXXXXXXXXXXX0"; 
      labeltotalPoints.AutoSize = true; 
      labeltotalPoints.BackColor = Color.White; 
        // labeltotalPoints.; 
      panel.Controls.Add(labeltotalPoints); 

      for (int i = 1; i <= 5; i++) 
      { 
       CheckBox checkBox = new CheckBox(); 
       checkBox.Name = String.Format("checkBox{0}", i); 
       checkBox.Text = ""; 
       checkBox.Width = 20; 
       checkBox.Height = 15; 
       checkBox.Location = new Point(chkBoxX, chkBoxY); 
       chkBoxX += 26; 

       checkBox.CheckedChanged += checkBox_CheckedChanged; 

       panel.Controls.Add(checkBox); 

      } 

      for (int j = 1; j <= 5; j++) 
      { 
       TextBox tb = new TextBox(); 
       tb.Name = String.Format("textBox{0}", j); 
       tb.Width = 60; 
       tb.Location = new Point(txtBoxX, txtBoxY); 
       txtBoxX += 80; 
       tb.TextChanged += txtBox_CheckedChanged; 
       panel.Controls.Add(tb); 
      } 

      chkBoxX -= (5 * 26); 
      txtBoxX -= (5 * 80); 

     } 

     private void txtBox_CheckedChanged(object sender, EventArgs e) 
     { 

      int total = 0; int points = 0; 

      foreach (object tb in ((TextBox)sender).Parent.Controls) 
      { 

       if (tb is TextBox) 
       { 
        if (!string.IsNullOrEmpty(((TextBox)tb).Text)) 
        { 
         if (!int.TryParse(((TextBox)tb).Text, out points)) 
         { 
          ((TextBox)tb).Text = ""; 
         } 

          total += points; 
        } 
       } 
      } 

      (((TextBox)sender).Parent.Controls["labelTxtBoxPoints"]).Text = Convert.ToString(total); 



     } 

     private void checkBox_CheckedChanged(object sender, EventArgs e) 
     { 

      int counter = 0; 

      foreach (object cb in ((CheckBox)sender).Parent.Controls) 
      { 
       if (cb is CheckBox) 
       { 
        if (((CheckBox)cb).Checked) 
        { 
         counter++; 
        } 
       } 

      } 

      (((CheckBox)sender).Parent.Controls["labelChkBoxPoints"]).Text = Convert.ToString(counter); 

     } 
    } 
} 
+0

它是如何工作的?你有什麼感受? –

+0

所以你想在每個組的底部添加點在下面的總點數? –

+1

@ user3956566是的,正確的。 – Iljaminati

回答

1

爲什麼不計算兩個事件結束時的「點」標籤總和?
這是好的和簡單的checkBox_CheckedChanged結束(你可以更有效地做到這一點,但我不這樣是有原因的......)
只需撥打TotalPoints(),txtBox_CheckedChanged

int TotalPoints() 
{ 
     int total = (from i in GetControlsWithPoint(this) 
        where i.Text != null && i.Text != string.Empty 
        select Convert.ToInt32(i.Text)).Sum(); 
     // MessageBox.Show("total" + total); 
     return total; 
} 

List<Control> GetControlsWithPoint(Control parent) 
{ 
     List<Control> results = new List<Control>(); 
     if (parent == null) 
      return results; 

     foreach (Control item in parent.Controls) 
     { 
      if (item.Name == "labelChkBoxPoints" || item.Name == "labelTxtBoxPoints") 
       results.Add(item); 
      results.AddRange(GetControlsWithPoint(item)); 
     } 

     return results; 

} 

更新

如果你只是想每個面板的總和所有你需要做的是改變TotalPoint方法只搜索您的面板

int TotalPoints(Panel p) 
{ 
     int total = (from i in GetControlsWithPoint(p) where i.Text != null && i.Text != string.Empty select Convert.ToInt32(i.Text)).Sum(); 
     // MessageBox.Show("total" + total); 
     return total; 
    } 

在您的活動結束內部, s

Panel p = (((Control)sender).Parent) as Panel; 
TotalPoints(p); 
+0

我測試了這個。但是這不會區分這些面板。你可以在這裏看到我的意思http://i.imgur.com/LpRTpsH.gif在panel2中增加了panel1的點數,但在panel2中,它應該被分開計算。 – Iljaminati

+0

@Iljaminati認爲你只想要總和。如果你想要當前面板的總和你必須修改方法一點,我更新了我的答案 –

+0

非常感謝。目前其他答案難以讓我站起來。 – Iljaminati

1

我會用一個TextBoxstatic int totalTotalPoints =0;

添加的TextBlock每組標籤:

void AddElements(Panel panel) { 
    TextBlock textblock = new TextBlock(); 
    TextBlock.Name = "TBlock"; 

然後在每個你的方法哪裏有點變化,更新TBlock.text();

private void txtBox_CheckedChanged(object sender, EventArgs e) 
{ .... 
    total += points; 
    // Implement a method to determine if points increase or decrease 
    // of points change. 
    // So if (points -ve or if points +ve 
    totalTotalPoints += points or -=points change; 
    (((TextBlock)sender).Parent.Controls["TBlock"]).Text = Convert.ToString(totalTotalPoints); 
} 

private void checkBox_CheckedChanged(object sender, EventArgs e) 
{ ... 
    counter++; 

    totalTotalPoints++; 
    (((CheckBox)sender).Parent.Controls["TBlock"]).Text = Convert.ToString(totalTotalPoints); 

} 

好的。這應該適合你。

一個側面說明:

在創建面板動態地分配他們的名字:

 for (int k = 1; k <= 3; k++) 
     { 
      Panel panel = new Panel(); 
      panel.Name = k.ToString(); 
      ... 
     } 
+0

當他檢查了3個複選框並取消選中一個時,這也可以起作用,所以他只計算2? – Iljaminati

+0

我使用C#而不是Android。 – Iljaminati

+0

omg,同樣的原則將工作,對不起,我在兩個atm編碼項目..我會編輯它。 java和c#非常相似。和xaml amd xml原理類似。 –

3

我會使用微軟的無框架這一點(的NuGet 「RX-主」 & 「RX-的WinForms」/ 「RX-WPF」)。

讓我來創建一些功能,以相當緊湊的方式做你想做的事。

對於需要此功能的複選框:

Func<IEnumerable<CheckBox>, IObservable<int>> makeCheckBoxCounter = cbs => 
    cbs 
     .Select(cb => Observable.FromEventPattern(h => cb.Click += h, h => cb.Click -= h)) 
     .Merge() 
     .Select(ep => cbs.Where(cb2 => cb2.Checked == true).Count()); 

這讓我通過複選框列表的功能和它返回一個IObservable<int>這給了我一個可觀察序列的檢查複選框的總和。

你使用這樣的:

IDisposable checkBoxesSubscription = 
    makeCheckBoxCounter(new[] { checkBox1, checkBox2, checkBox3, checkBox4, checkBox5, }) 
     .Subscribe(x => label1.Text = x.ToString()); 

我測試過此代碼,它完美的作品。

你可以通過調用下面將其關閉:由於需要分析文本

checkBoxesSubscription.Dispose(); 

文本框的版本稍微複雜一些。它看起來像這樣:

Func<IEnumerable<TextBox>, IObservable<int>> makeTextBoxCounter = tbs => 
    tbs 
     .Select(tb => 
      Observable 
       .FromEventPattern(h => tb.TextChanged += h, h => tb.TextChanged -= h)) 
     .Merge() 
     .Select(ep => 
     { 
      var total = 0; 
      foreach (var tb2 in tbs) 
      { 
       var value = 0; 
       if (int.TryParse(tb2.Text, out value)) 
       { 
        total += value; 
       } 
      } 
      return total; 
     }); 

和認購是這樣的:

var textBoxesSubscription = 
    makeTextBoxCounter(new[] { textBox1, textBox2, textBox3, textBox4, textBox5, }) 
     .Subscribe(x => label2.Text = x.ToString()); 

我測試過這兩種。

+0

當我在C#中有更多的知識時,我會試試這個。 – Iljaminati

相關問題