2013-04-15 88 views
5

我在c#中有一個winform,我動態地創建了兩個組合框和一個文本框。當用戶選擇說月份和年份並在文本框中輸入一個值時,我希望在單擊按鈕時保存相關的組合框值。默認情況下,月份和年份組合框將選擇當前的月份和年份。獲取動態文本框和組合框的選定值

在同一屏幕中還有另一部分數據將填充上個月,例如組合框和文本框中的當前年份從1月到3月(如果可用)。

我不確定這種方法是否正確,或者我應該使用datagridview。下面是截圖和我的代碼。有關我如何做到這一點的任何建議。

截圖 enter image description here

代碼

private void createComboMonths() 
{ 
    int width = 79; 
    int height = 24; 
    int spacing = 28; 
    ComboBox[] SubMonths = new ComboBox[12]; 
    for (int i = 0; i <= 11; ++i) 
    { 
     SubMonths[i] = new ComboBox(); 
     SubMonths[i].Name = "SubMonths"; 
     SubMonths[i].DropDownStyle = ComboBoxStyle.DropDownList; 
     SubMonths[i].Size = new Size(width, height); 
     SubMonths[i].Location = new Point(56, (i * height) + spacing); 
     SubMonths[i].Items.Add("January"); 
     SubMonths[i].Items.Add("February"); 
     SubMonths[i].Items.Add("March"); 
     SubMonths[i].Items.Add("April"); 
     SubMonths[i].Items.Add("May"); 
     SubMonths[i].Items.Add("June"); 
     SubMonths[i].Items.Add("July"); 
     SubMonths[i].Items.Add("August"); 
     SubMonths[i].Items.Add("September"); 
     SubMonths[i].Items.Add("October"); 
     SubMonths[i].Items.Add("November"); 
     SubMonths[i].Items.Add("December"); 
     SubMonths[i].SelectedItem = DateTime.Today.ToString("MMMM"); 
     plSubscription.Controls.Add(SubMonths[i]); 

    } 
} 


private void createComboYears() 
{ 
    int width = 79; 
    int height = 24; 
    int spacing = 28; 
    ComboBox[] SubYears = new ComboBox[12]; 
    for (int i = 0; i <= 11; ++i) 
    { 
     SubYears[i] = new ComboBox(); 
     SubYears[i].Name = "SubYears"; 
     SubYears[i].DropDownStyle = ComboBoxStyle.DropDownList; 
     SubYears[i].Size = new Size(width, height); 
     SubYears[i].Location = new Point(145, (i * height) + spacing); 
     plSubscription.Controls.Add(SubYears[i]); 
     fillComboData(SubYears[i]); // Function to fill the last 5 years 
    } 
} 



private void createTextBoxes() 
{ 
    int width = 79; 
    int height = 24; 
    int spacing = 28; 
    TextBox[] subAmt = new TextBox[12]; 
    for (int i = 0; i <= 11; ++i) 
    { 
     subAmt[i] = new TextBox(); 
     subAmt[i].Name = "SubAmt" + i; 
     subAmt[i].Border.Class = "TextBoxBorder"; 
     subAmt[i].Size = new Size(width, height); 
     subAmt[i].Margin = new Padding(10, 10, 10, 10); 
     subAmt[i].Location = new Point(279, (i * height) + spacing); 
     subAmt[i].KeyPress += new KeyPressEventHandler(txtJanAmt_KeyPress); 
     plSubscription.Controls.Add(subAmt[i]); 

    } 
} 


private void btnSave_Click(object sender, EventArgs e) 
{ 
    DataTable dtSubs = new DataTable(); 
    dtSubs.Columns.Add("SubscriberID", typeof(string)); 
    dtSubs.Columns.Add("Month", typeof(string)); 
    dtSubs.Columns.Add("Year", typeof(string)); 
    dtSubs.Columns.Add("SubAmt", typeof(string)); 
    DataRow row = dtSubs.NewRow(); 
    foreach (Control c in plSubscription.Controls) 
    { 
     //<- Not sure how do I get the selected row as in the screenshot 
    } 
} 

編輯1

我用下面的代碼從數據表,但無法獲取數據做如下

  1. 我如何設置組合框的值,每當有可用的數據我想該行是作爲選擇的,當我從數據表
  2. 對TextBox得到它如何從DataTable中
  3. 獲得的價值只讀。

在此先感謝

更改代碼

for (int i = 0; i < dt.Rows.Count; i++) 
{ 
    #region Grid Column Names 
    DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn(); 
    mntCmb.HeaderText = "Month"; 
    mntCmb.Name = "Month"; 
    mntCmb.DataSource = dt; 
    mntCmb.DisplayMember = "paidformonth"; 
    mntCmb.ValueMember = "paidformonth"; 
    // <-How do I set the column as selected. 

    DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn(); 
    yearCmb.HeaderText = "Year"; 
    yearCmb.Name = "Year"; 
    yearCmb.DisplayMember = "paidforyear"; 
    yearCmb.ValueMember = "paidforyear"; 
    // <-How do I set the column as selected. 

    DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn(); 
    amount.HeaderText = "Subscription Amount"; 
    amount.Name = "Subscription Amount"; 
    amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 
    // <-How do I set this column with the value from the datatable 

    #endregion 

    dgvSubscriptions.Columns.AddRange(mntCmb, yearCmb, amount); 
} 

編輯2

我似乎是困惑,爲什麼我越來越有6列3行。該數據表只有2行和3列。我正在使用上面的代碼。我添加了ID列以查看會發生什麼。請參閱下面的截圖。我有

dgvSubscriptions.AllowUserToAddRows = true 

因爲我希望用戶添加行並輸​​入更多的數據進行保存。我在這裏想要做的是獲得支付月份/年的訂閱列表,並允許用戶添加訂閱,例如假設1月到4月支付6月5月。

enter image description here

編輯3

我甚至設置DataPropertyName而不是ValueMember依然沒有改變

編輯代碼

DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn(); 
yearCmb.HeaderText = "Year"; 
yearCmb.Name = "Year"; 
//yearCmb.DataSource = dt; 
yearCmb.DisplayMember = "paidforyear"; 
//yearCmb.ValueMember = "paidforyear"; 
yearCmb.DataPropertyName= "paidforyear"; 
yearCmb.DefaultCellStyle.NullValue = dt.Rows[i][2].ToString(); 
yearCmb.ReadOnly = true; 
dgvSubscriptions.Columns.Add(yearCmb); 

編輯4

下面是導致重複列

dgvSubscriptions.AutoGenerateColumns = false; 
dgvSubscriptions.ColumnCount = 1; 
dgvSubscriptions.Columns[0].Name = "ID"; 
dgvSubscriptions.Rows.Clear(); 
for (int i = 0; i <dt.Rows.Count; i++) 
{ 
    dgvSubscriptions.Rows.Add(); 
    #region Grid Column Names 
    DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn(); 
    mntCmb.HeaderText = "Month"; 
    mntCmb.Name = "Month"; 
    //mntCmb.DataSource = dt; 
    mntCmb.DisplayMember = "paidformonth"; 
    mntCmb.DataPropertyName = "paidformonth"; 
    //mntCmb.ValueMember = "paidformonth"; 
    mntCmb.DefaultCellStyle.NullValue = dt.Rows[i][1].ToString(); 
    mntCmb.ReadOnly = true; 
    dgvSubscriptions.Columns.Add(mntCmb); 


    DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn(); 
    yearCmb.HeaderText = "Year"; 
    yearCmb.Name = "Year"; 
    //yearCmb.DataSource = dt; 
    yearCmb.DisplayMember = "paidforyear"; 
    //yearCmb.ValueMember = "paidforyear"; 
    yearCmb.DataPropertyName= "paidforyear"; 
    yearCmb.DefaultCellStyle.NullValue = dt.Rows[i][2].ToString(); 
    yearCmb.ReadOnly = true; 
    dgvSubscriptions.Columns.Add(yearCmb); 

    DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn(); 
    amount.HeaderText = "Subscription Amount"; 
    amount.Name = "Subscription Amount"; 
    amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 
    //amount.DataPropertyName = dt.Rows[i][2].ToString(); 
    amount.DataPropertyName="subamount"; 
    amount.DefaultCellStyle.NullValue = dt.Rows[i][0].ToString(); 
    amount.ReadOnly = true; 
    dgvSubscriptions.Columns.Add(amount); 

    #endregion 

} 

編輯5

我用IRSOG代碼進行一些修改和下面是完整的工作代碼的實際代碼。

工作守則

public struct Data 
{ 
    public List<string> Mon { get; set; } 
    public List<string> Year { get; set; } 
} 

private void fillGridData(DataTable dt) 
{ 
    List<string> Mon = new List<string>() { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; 

    List<string> Year = new List<string>(); 
    int CurrentYear = DateTime.UtcNow.Year; 
    int NextYear = CurrentYear + 1; 
    int LastFiveYears = CurrentYear - 5; 
    for (int i = LastFiveYears; i <= NextYear; i++) 
    { 
    Year.Add(i.ToString()); 
    } 
    List<Data> _Data = new List<Data>(); 
    for (int i = 1; i <= 12; i++) 
    { 
    _Data.Add(new Data() { Mon = Mon, Year = Year }); 
    } 

    dgvSubscriptions.Rows.Clear(); 
    dgvSubscriptions.Refresh(); 
    dgvSubscriptions.Visible = true; 
    dgvSubscriptions.ColumnHeadersDefaultCellStyle.Font = new Font("Trebuchet MS", 8F, FontStyle.Regular); 
    dgvSubscriptions.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; 
    dgvSubscriptions.AutoResizeColumns(); 
    dgvSubscriptions.AllowUserToResizeColumns = true; 
    dgvSubscriptions.AllowUserToOrderColumns = true; 
    dgvSubscriptions.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; 
    dgvSubscriptions.Dock = DockStyle.None; 
    dgvSubscriptions.BackgroundColor = this.BackColor; 
    dgvSubscriptions.BorderStyle = BorderStyle.None; 
    dgvSubscriptions.AllowUserToAddRows = true; 


    // If dt.Rows.Count > 0 then show the data - do not allow to change existing data 
    if (dt.Rows.Count > 0) 
    { 

    dgvSubscriptions.Rows.Clear(); 
    dgvSubscriptions.Refresh(); 

    #region Grid Column Names 
    dgvSubscriptions.AutoGenerateColumns = false; 
    dgvSubscriptions.Rows.Clear(); 
    DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn(); 
    mntCmb.HeaderText = "Month"; 
    mntCmb.Name = "Month"; 
    mntCmb.DataSource = Mon; 
    mntCmb.DefaultCellStyle.NullValue = ""; 
    dgvSubscriptions.Columns.Add(mntCmb); 

    DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn(); 
    yearCmb.HeaderText = "Year"; 
    yearCmb.Name = "Year"; 
    yearCmb.DataSource = Year; 
    yearCmb.DefaultCellStyle.NullValue = ""; 
    dgvSubscriptions.Columns.Add(yearCmb); 

    DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn(); 
    amount.HeaderText = "Subscription Amount"; 
    amount.Name = "Subscription Amount"; 
    amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 
    amount.DefaultCellStyle.NullValue = ""; 
    dgvSubscriptions.Columns.Add(amount); 
    #endregion 

    #region Populate Grid 
    for (int i = 0; i <dt.Rows.Count; i++) 
    { 
     dgvSubscriptions.Rows.Add(); 

     dgvSubscriptions.Rows[i].Cells[0].Value = dt.Rows[i][1].ToString(); // Month 
     dgvSubscriptions.Rows[i].Cells[0].ReadOnly = true; // do not allow the user to make changes 
     dgvSubscriptions.Rows[i].Cells[1].Value = dt.Rows[i][2].ToString(); // Year 
     dgvSubscriptions.Rows[i].Cells[1].ReadOnly = true; // do not allow the user to make changes 
     dgvSubscriptions.Rows[i].Cells[2].Value = dt.Rows[i][0].ToString(); // Subscription amount 
     dgvSubscriptions.Rows[i].Cells[2].ReadOnly = true; // do not allow the user to make changes 

    } 
    #endregion 

    } 
    else // We come here if dt.Rows.Count is 0 we allow the user to select and save 
    { 

    #region Grid Column Names 
    DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn(); 
    mntCmb.HeaderText = "Month"; 
    mntCmb.Name = "Month"; 
    mntCmb.DataSource = Mon; 

    DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn(); 
    yearCmb.HeaderText = "Year"; 
    yearCmb.Name = "Year"; 
    yearCmb.DataSource = Year; 

    DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn(); 
    amount.HeaderText = "Subscription Amount"; 
    amount.Name = "Subscription Amount"; 
    amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 
    #endregion 
    dgvSubscriptions.Columns.AddRange(mntCmb, yearCmb, amount); 

    dgvSubscriptions.DataSource = _Data; 
    } 
    dgvSubscriptions.RowsDefaultCellStyle.Font = new Font("Trebuchet MS", 8F, FontStyle.Regular); 

} 
+0

您可以簡單地把控制C作爲文本框,並檢查它是否不爲空,那麼得到的文本框 –

+1

文本有您使用[DataGridView中(http://msdn.microsoft.com/en-us考慮/library/system.windows.forms.datagridview.aspx)取而代之? –

+0

@RajeevKumar我能做到這一點,但如果你再看到我的截圖我想在文本框 – Adrian

回答

2

而不是使用這個的,使用DataGridView 試試這個:

隨着調用即可獲得選定行信息的GetCurrentRowValues方法。

完整代碼

public Form1() 
     { 
      InitializeComponent(); 
      dataGridView1.MultiSelect = false; 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      List<string> Mon = new List<string>() { "January", "February", "March", "April", "May", " June", "July", "August", "September", "October", "November", "December" }; 
      List<string> Year = new List<string>() { "2001", "2002", "2003", "2004", "2005", "2006" }; 
      List<Data> _Data = new List<Data>(); 
      for (int i = 1; i <= 12; i++) 
      { 
       _Data.Add(new Data() { Mon = Mon, Year = Year }); 
      } 
      DataGridViewComboBoxColumn moonCmb = new DataGridViewComboBoxColumn(); 
      moonCmb.HeaderText = "Month"; 
      moonCmb.Name = "Month"; 
      moonCmb.DataSource = Mon; 

      DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn(); 
      yearCmb.HeaderText = "Year"; 
      yearCmb.Name = "Year"; 
      yearCmb.DataSource = Year; 
      DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn(); 
      amount.HeaderText = "Amount"; 
      amount.Name = "Amount"; 
      dataGridView1.Columns.AddRange(moonCmb, yearCmb, amount); 

      dataGridView1.DataSource = _Data; 

     } 

     private void GetCurrentRowValues() 
     { 
      var mon = dataGridView1.CurrentRow.Cells["Month"].Value; 
      var year = dataGridView1.CurrentRow.Cells["Year"].Value; 
      var amont = dataGridView1.CurrentRow.Cells["Amount"].Value; 
     } 

    } 
    public struct Data 
    { 
     public List<string> Mon { get; set; } 
     public List<string> Year { get; set; } 
    } 

結果

enter image description here

新編輯從數據表

 #region Grid Column Names 
     dgvSubscriptions.AutoGenerateColumns = false; 
     dgvSubscriptions.ColumnCount = 1; 
     dgvSubscriptions.Columns[0].Name = "ID"; 
     dgvSubscriptions.Rows.Clear(); 

     DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn(); 
     mntCmb.HeaderText = "Month"; 
     mntCmb.Name = "Month"; 
     //mntCmb.DataSource = dt; 
     mntCmb.DisplayMember = "paidformonth"; 
     mntCmb.DataPropertyName = "paidformonth"; 
     //mntCmb.ValueMember = "paidformonth"; 
     mntCmb.DefaultCellStyle.NullValue = ""; 
     mntCmb.ReadOnly = true; 
     mntCmb.Items.Add("april"); 
     mntCmb.Items.Add("jun"); 
     mntCmb.Items.Add("jull"); 
     dgvSubscriptions.Columns.Add(mntCmb); 

     DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn(); 
     yearCmb.HeaderText = "Year"; 
     yearCmb.Name = "Year"; 
     //yearCmb.DataSource = dt; 
     yearCmb.DisplayMember = "paidforyear"; 
     //yearCmb.ValueMember = "paidforyear"; 
     yearCmb.DataPropertyName = "paidforyear"; 
     yearCmb.DefaultCellStyle.NullValue = ""; 
     yearCmb.Items.Add("2001"); 
     yearCmb.Items.Add("2002"); 
     yearCmb.Items.Add("2003"); 
     yearCmb.ReadOnly = true; 
     dgvSubscriptions.Columns.Add(yearCmb); 
     DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn(); 
     amount.HeaderText = "Subscription Amount"; 
     amount.Name = "Subscription Amount"; 
     amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 
     //amount.DataPropertyName = dt.Rows[i][2].ToString(); 
     amount.DataPropertyName = "subamount"; 
     amount.DefaultCellStyle.NullValue = ""; 
     amount.ReadOnly = true; 
     dgvSubscriptions.Columns.Add(amount); 
     #endregion 

填充它

 for (int i = 0; i < dt.Rows.Count; i++) 
     { 
      dgvSubscriptions.Rows.Add(); 
      dgvSubscriptions.Rows[i].Cells[0].Value = dt.Rows[i][0].ToString(); 
      dgvSubscriptions.Rows[i].Cells[1].Value = dt.Rows[i][1].ToString(); 
      dgvSubscriptions.Rows[i].Cells[2].Value = dt.Rows[i][2].ToString(); 
      dgvSubscriptions.Rows[i].Cells[3].Value = dt.Rows[i][0].ToString(); 
     } 
+0

嗯...我開始像這樣,半途而廢:)。讓我試一下你的代碼並看看。只有一個問題 - 我的列表字符串年可想有過去5年加上當前和明年 – Adrian

+0

你的代碼的工作只需要找出如何從金額列 – Adrian

+0

@Adrian輸入數字和小數點限制用戶:第一個問題是不難實現,且秒的問題:你必須創建自定義的dataGridView的列,其中地方你想要的任何控制:HTTP://msdn.microsoft.com/en-us/library/7tas5c80.aspx – KF2

1

的形式ActiveControl屬性可以幫助你。

var focusedCtrl = this.ActiveControl; 
var siblings = Controls.Where(c => c.Location.Y == focusedCtrl.Location.Y).ToList(); 
foreach (Control c in siblings) 
{ 
    // all thise controls are on the same row, providede that the allign 
} 

我仍然會建議DataGridView。對於一個看起來像你的結構,它似乎是一個更好的選擇。

+0

感謝讓我看看我是否可以使用datagridview。我嘗試使用DataGridView時遇到的問題是如何動態地填充組合框列。我會嘗試看看 – Adrian

+0

@Adrian我[見](http://stackoverflow.com/questions/7648648/dynamic-combobox-in-a-datagridview)你的問題。也許你需要更好的GridView。我總是使用[XtraGrid](http://www.devexpress.com/Products/NET/Controls/WinForms/Grid/),但它不是免費的。 –

1

我會去與DataGridView的,但如果你仍然想保持這種結構你可能要更新keyPressed事件處理程序看起來像這樣

private string lastUsedTextBox = string.Empty; 
private string lastEnteredValue = string.Empty; 

private void txtJanAmt_KeyPress(object sender, KeyPressEventArgs e) 
{ 
lastUsedTextBox = (sender as TextBox).Name;      
lastEnteredValue = (sender as TextBox).Text;      
} 

而且那麼當你按下保存按鈕時,你已經存儲了所有的東西。

如果您需要保存所有數據,您可以使用字典或類似的東西。

+0

謝謝我已經去了datagridview,但仍然有一些問題檢查我編輯的問題。不知道如何設置組合框的DataTable中的值 – Adrian