获取动态文本框和组合框的选定值

时间:2013-04-15 06:16:22

标签: c# winforms

我在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. 对于文本框,如何从数据表中获取值
  3. 每当有可用数据时,我希望该行只读。
  4. 提前致谢

    更改了代码

    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

    我似乎很困惑为什么我得到3行6列。数据表只有2行3列。我正在使用上面的代码。我添加了ID列,看看会发生什么。请参见下面的截图。我有

    dgvSubscriptions.AllowUserToAddRows = true
    

    因为我希望用户添加行并输​​入更多数据进行保存。我在这里要做的是获得已支付的月份/年份的订阅列表,并允许用户添加订阅,例如5月,6月,假设1月到4月已经支付。

    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);
    
    }
    

3 个答案:

答案 0 :(得分: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();
        }

答案 1 :(得分: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。对于看起来像你的结构来说,这似乎是一个更好的选择。

答案 2 :(得分: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;                       
}

然后当您按下保存按钮时,您将所有内容存储在此处。

如果您需要保存所有数据,可以使用字典或类似的东西。