2017-05-22 46 views
-2

我想要訪問一個按鈕內的數組,我創建一個新的對象時創建,但按鈕出陣列邊界時,我使用他(但訪問非常數組不能訪問動態按鈕裏面

public void updateExpensesLabels() 
    { 
     deleteExpensesLabels(); 
     for (int i = 0; i < categories.Length; i++) 
     { 
      if (categories[i] != null) 
      { 
       categories[i].test(); 
       addExpense.Click += (s, e) => 
       { 
        categories[i].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text)); 
       }; 
      } 
     } 
    } 

請注意類別[I]進入低谷,沒有問題,並打印出隨機文本:按鈕產量沒問題)

相關代碼(請參閱下面的類和消費類)之外相同的索引它應該,但是當我將測試放入按鈕內時,當我單擊按鈕時問題會消失。

編輯:我提出的測試一點更明顯,此時,碼的輸出爲「對象不爲空按鈕的外側」和不是因爲索引的壓碎出陣列的

  if (categories[i] == null) 
      { 
       MessageBox.Show("Its null outside the button code"); 
      } 
      else 
      { 
       MessageBox.Show("Its not null outside the button code"); 
      } 
      addExpense.Click += (s, e) => 
      { 
       if (categories[i] == null) 
       { 
        MessageBox.Show("Its null inside the button code"); 
       } 
       categories[i].test(); 
       categories[i].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text)); 
      }; 

編輯2: 例外的是System.IndexOutOfRangeException 細節 -

System.IndexOutOfRangeException occurred 
    HResult=0x80131508 
    Message=האינדקס נמצא מחוץ לגבולות המערך. 
    Source=Budget Managment Prog 
    StackTrace: 
    at Budget_Managment_Prog.Form1.<>c__DisplayClass21_0.<updateExpensesLabels>b__0(Object s, EventArgs e) in C:\Users\user\OneDrive\Budget Management Prog\Budget Managment Prog\Budget Managment Prog\Form1.cs:line 213 
    at System.Windows.Forms.Control.OnClick(EventArgs e) 
    at System.Windows.Forms.Button.OnClick(EventArgs e) 
    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 
    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
    at System.Windows.Forms.Control.WndProc(Message& m) 
    at System.Windows.Forms.ButtonBase.WndProc(Message& m) 
    at System.Windows.Forms.Button.WndProc(Message& m) 
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.Run(Form mainForm) 
    at Budget_Managment_Prog.Program.Main() in C:\Users\user\OneDrive\Budget Management Prog\Budget Managment Prog\Budget Managment Prog\Program.cs:line 19 

Forms1 -

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Budget_Managment_Prog 
{ 
     /// <summary> 
     /// Expenses Section 
     /// </summary> 
     Category[] categories = new Category[0]; 
     TabPage[] categoryTab = new TabPage[0]; 
     Label[] expenseLabel = new Label[0]; 
     private void addCategoryButton_Click(object sender, EventArgs e) 
     { 
      increaseCategories(); 
      categories[Category.categoryNum] = new Category(Category.categoryNum, newCategoryTextBox.Text); 
      Category.categoryNum++; 
      increaseTabs(); 
      updateExpensesLabels(); 
     } 

     private void increaseTabs() 
     { 
      TabPage[] temp = new TabPage[categoryTab.Length + 1]; 
      for (int i = 0; i < categoryTab.Length; i++) 
      { 
       temp[i] = categoryTab[i]; 
      } 
      categoryTab = temp; 
     } 

     private void increaseCategories() 
     { 
      Category[] temp = new Category[categories.Length + 1]; 
      for (int i = 0; i < categories.Length; i++) 
      { 
       temp[i] = categories[i]; 
      } 
      categories = temp; 
     } 

     public void updateExpensesLabels() 
     { 
      deleteExpensesLabels(); 
      for (int i = 0; i < categories.Length; i++) 
      { 
       if (categories[i] != null) 
       { 

        categoryTab[i] = new TabPage(); 
        categoryTab[i].Text = categories[i].name; 
        categoryTabControl.Controls.Add(categoryTab[i]); 
        Label addExpenseLabel = new Label(); addExpenseLabel.Text = "New Expense Here?"; 
        addExpenseLabel.AutoSize = true; 
        addExpenseLabel.Top = 10; addExpenseLabel.Left = 15; categoryTab[i].Controls.Add(addExpenseLabel); 
        Label nameLabel = new Label(); nameLabel.Text = "Name:"; 
        nameLabel.AutoSize = true; 
        nameLabel.Top = 25; nameLabel.Left = 25; categoryTab[i].Controls.Add(nameLabel); 
        Label amountLabel = new Label(); amountLabel.Text = "Money:"; 
        amountLabel.AutoSize = true; 
        amountLabel.Top = 25; amountLabel.Left = 250; categoryTab[i].Controls.Add(amountLabel); 
        TextBox expenseName = new TextBox(); expenseName.Top = 50; expenseName.Left = 25; categoryTab[i].Controls.Add(expenseName); 
        TextBox expenseAmount = new TextBox(); expenseAmount.Top = 50; expenseAmount.Left = 250; categoryTab[i].Controls.Add(expenseAmount); 
        categories[i].test(); 
        Button addExpense = new Button(); 
        addExpense.Click += (s, e) => 
        { 
         categories[i].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text)); 
        }; 
        categoryTab[i].Controls.Add(addExpense); 
        int entries = 0; 
        int labelNum = 0; 
        for (int j = 0; j < categories[i].expenses.Length; j++) 
        { 
         expenseLabel[labelNum] = new Label(); 
         expenseLabel[labelNum].Text = Convert.ToString(categories[i].expenses[labelNum].num); 
         expenseLabel[labelNum].Top = 80 + (30 * entries); expenseLabel[labelNum].Left = 25; 
         categoryTab[i].Controls.Add(expenseLabel[labelNum]); 
         increaseLabelArray(); 
         labelNum++; 


        } 
       } 
      } 
     } 

     private void deleteExpensesLabels() 
     { 
      for (int i = 0; i< categoryTab.Length; i++) 
      { 
       categoryTabControl.Controls.Remove(categoryTab[i]); 
      } 
     } 

     private void increaseLabelArray() 
     { 
      Label[] temp = new Label[expenseLabel.Length + 1]; 
      for (int i = 0; i < expenseLabel.Length; i++) 
      { 
       temp[i] = expenseLabel[i]; 
      } 
      expenseLabel = temp; 
     } 
    } 
} 

類別 -

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 


namespace Budget_Managment_Prog 
{ 
    class Category 
    { 
     private int numOfExpenses = 0; 
     public Expense[] expenses = new Expense[0]; 
     public static int categoryNum = 0; 
     public string name; 
     public Category(int num1, string name1) 
     { 
      categoryNum = num1; 
      name = name1; 
     } 

     public void createNewExpense(int expense2, string name2) 
     { 

      increaseArray(); 
      expenses[numOfExpenses] = new Expense(numOfExpenses, expense2, name2); 
      numOfExpenses ++;   


     } 

     public void deleteExpense(int num) 
     { 
      if (num > expenses.Length || num < 1) 
      { 
       MessageBox.Show("Invalid Entry for deletion, make sure the number is not bigger than the biggest person or smaller than 1"); 
      } 
      else 
      { 
       Expense[] temp = new Expense[expenses.Length - 1]; 
       for (int i = 0; i < expenses.Length; i++) 
       { 
        if (expenses[i].num < num) 
        { 
         temp[i] = expenses[i]; 
        } 
        if (expenses[i].num > num) 
        { 
         expenses[i].num--; 
         temp[i - 1] = expenses[i]; 
        } 
       } 
       expenses = temp; 
       numOfExpenses--; 
      } 
     } 
     public void increaseArray() 
     { 
      Expense[] temp = new Expense[expenses.Length + 1]; 
      for (int i = 0; i < expenses.Length; i++) 
      { 
       temp[i] = expenses[i]; 
      } 
      expenses = temp; 

     } 

     public void test() 
     { 
      MessageBox.Show("The Problem is in category or expense classes"); 
     } 
    } 
} 

費用 -

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Budget_Managment_Prog 
{ 
    class Expense 
    { 
     public int num; 
     public int expense; 
     public string name; 
     public Expense(int num1, int expense1, string name1) 
     { 
      num = num1; 
      expense = expense1; 
      name = name1; 
     } 
    } 


} 
+0

你有數組的長度爲0.它沒有元素。您無法訪問任何元素,因爲沒有任何內容,您將跳出界限。 –

+0

你在說什麼?你讀過我說過的嗎?我只是訪問了按鈕代碼之外的相同索引 – Tomer

+0

調試您的代碼並查看您的陣列。 –

回答

2

修訂

,我發現你的問題。它在這categories[i]。如果您調試該程序,您會看到當您添加new Category時,您的i is 0和您的categories[i].test()將正常工作。但問題是,您的button click總是在loop's iteration之後,換句話說,當button click工作時i已經是equal to 1而您的categories[i]將超出界限。
如果你改變你的代碼中添加按鈕,這個你不會得到例外的部分更多:

categories[i].test(); 
var number = i; 
Button addExpense = new Button(); 
addExpense.Click += (s, e) => 
{      
    categories[number].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text)); 
}; 

您已經聲明

public Expense[] expenses = new Expense[0]; 

,那麼你正在嘗試做到這一點

expenses[numOfExpenses] = new Expense(numOfExpenses, expense2, name2); 

其中numOfExpenses不在expenseslength,因爲它是你聲明的空數組。

我建議你使用List<Expense>代替Expense[],這樣就不會被你給初始化時,當你需要添加新的費用,你只用expenses.Add(new Expense(numOfExpenses, expense2, name2)).

這裏是例如數量限制你怎麼做

class Category 
{ 
    public List<Expense> expenses = new List<Expense>(); 
    public static int categoryNum = 0; 
    public string name; 
    public Category(int num1, string name1) 
    { 
     categoryNum = num1; 
     name = name1; 
    } 

    public void createNewExpense(int expense2, string name2) 
    { 
     expenses.Add(new Expense(expenses.Count, expense2, name2)); 
    } 

    public void deleteExpense(int num) 
    { 
     if (num > expenses.Count || num < 1) 
     { 
      MessageBox.Show("Invalid Entry for deletion, make sure the number is not bigger than the biggest person or smaller than 1"); 
     } 
     else 
     { 
      expenses.RemoveAt(num); 
     } 
    } 
    public void test() 
    { 
     MessageBox.Show("The Problem is in category or expense classes"); 
    } 
} 
+0

Misclick,我正在編輯,回來3分鐘。 我已經按照你所說的編輯了代碼,並且使得數組從一個開始,但它仍然不會修復它,我將更進一步向您顯示這一點: addExpense.Click + =(s,e )=> { categories [i] .createNewExpense(Convert.ToInt32(expenseAmount.Text),Convert.ToString(expenseName.Text)); }; categoryTab [i] .Controls.Add(addExpense); 只有當我點擊按鈕時,代碼纔會崩潰。 – Tomer

+0

@Tomer看看我添加到我的回答中的'Category'類 –

+0

對不起,我不知何故錯過了,謝謝 – Tomer