5

2 つのコンボボックスとテキストボックスを動的に作成した c# の winform があります。ユーザーが月と年を選択してテキストボックスに値を入力すると、ボタンをクリックして保存すると、関連するコンボボックスの値が取得されます。デフォルトでは、月と年のコンボボックスには現在の月と年が選択されています。

同じ画面には、コンボボックスとテキストボックス (利用可能な場合) の今年の 1 月から 3 月のような前月のデータが入力される別の部分もあります。

このアプローチが正しいのか、datagridview を使用する必要があるのか​​ わかりません。以下はスクリーンショットと私のコードです。これを行う方法についての提案。

スクリーンショット ここに画像の説明を入力

コード

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. 利用可能なデータがあるときはいつでも、その行を読み取り専用にしたいです。

前もって感謝します

変更されたコード

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 月までが支払われたと仮定して、ユーザーがたとえば 5 月、6 月のサブスクリプションを追加できるようにすることです。

ここに画像の説明を入力

編集 3

ValueMember の代わりに DataPropertyName を設定しても、変更はありません

編集されたコード

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

}
4

3 に答える 3

2

これを使用する代わりに、これをDataGridView 試してください:

CallingGetCurrentRowValuesメソッドを使用すると、選択した行の情報を取得できます。

完全なコード

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

結果

ここに画像の説明を入力

新しい edit-From データ テーブル

        #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();
        }
于 2013-04-15T08:34:12.940 に答える