C# 如何从数据集中设置DataGridViewComboxColumn值

C# 如何从数据集中设置DataGridViewComboxColumn值,c#,winforms,datagridview,C#,Winforms,Datagridview,假设我有两张桌子: work_hours work_hours_id | date | _project_id 1 1.2. 10 2 1.2. 11 3 1.2. 10 project project_id | project_name 10 pr1 11 pr2 12 p

假设我有两张桌子:

 work_hours
 work_hours_id | date  | _project_id
     1            1.2.      10
     2            1.2.      11
     3            1.2.      10 

 project
 project_id | project_name
    10           pr1
    11           pr2
    12           pr3
在DataGridView中,我希望看到以下内容:

 work_hours_id | date | _person_id | project_name(DataGridViewComboBoxColumn)
     1            1.2.     10            pr1
     2            1.2.     11            pr2
     3            1.2.     10            pr1
1.我该怎么做? 2.如果我使用
SqlCommandBuilder
将pr1(
work\u hours\u id=3
)更改为pr3(
datagridviewcomboxcolumn
),则可以保存表
工时
中的更改

 string query = "SELECT work_hours.work_hours_id, work_hours.date FROM work_hours
           LEFT OUTER JOIN project ON work_hours._project_id = project.project_id ORDER BY work_hours.date;
         SELECT * FROM project ORDER BY project_name";

            SqlCommand sqlcmd = new SqlCommand(query, conn);
            da = new SqlDataAdapter(query, connectionString);
            cBuilder = new SqlCommandBuilder(da);
            dt = new DataTable();
            ds = new DataSet();
            da.Fill(dt);
            da.Fill(ds);

            DataGridViewComboBoxColumn columnCb = new DataGridViewComboBoxColumn();
            columnCb.DataPropertyName = "_project_id";

            columnCb.DataSource = ds.Tables[1];
            columnCb.ValueMember = "project_id";
            columnCb.DisplayMember = "project_name";

            bSource = new BindingSource();
            bSource.DataSource = dt;
            dataGridView1.DataSource = bSource;
            dataGridView1.Columns.Add(columnCb);

如果我没有误解,您希望设置datagridview的combobox列的数据源。您可以通过以下方式进行设置:

/// if you use OfType Method then you will get advantage of to use as normal control
/// means this method will give you advantage of can use all method and properties
/// of the control which you want to implement in DataGridView

/// Controls.OfType method will check all the columns and get an array with 
/// what you give as search criteria..here, the criteria is ComboboxColumn..
/// depends of your need you can give comboboxcell also..

/// Element at method selects the zero based index in array which filtered by criteria
/// if you use only one of the given type then you can use .First() instead of .ElementAt()


yourDataGridViewName.Controls.OfType<DataGridViewComboBoxColumn>()
.ElementAt(indexNoOfTheDGVComboBox).DataSource = YourDataRetrievingMethod; 
//i.e. ds.Tables[indexNoOfTheTable].Columns[IndexOfTheColumn]

/// and you can set DisplayMember and ValueMember as the same way.. 
/// i give combocell and combocolumn together to show the syntax.

yourDataGridViewName.Controls.OfType<DataGridViewComboBoxCell>()
.ElementAt(0).DisplayMember = "YourDisplay";

yourDataGridViewName.Controls.OfType<DataGridViewComboBoxCell>()
.ElementAt(0).ValueMember = "YourValue"; 
///若您使用of type方法,那个么您将获得用作普通控件的优势
///意味着此方法将为您提供可以使用所有方法和属性的优势
///要在DataGridView中实现的控件的
///Controls.OfType方法将检查所有列,并使用
///您给出的搜索条件。这里,条件是ComboboxColumn。。
///根据您的需要,您也可以提供comboboxcell。。
///方法中的元素选择按条件筛选的数组中从零开始的索引
///如果只使用给定类型中的一种,则可以使用.First()而不是.ElementAt()
yourDataGridViewName.Controls.OfType()
.ElementAt(indexNoOfTheDGVComboBox).DataSource=YourDataRetrievingMethod;
//i、 e.ds.Tables[indexNoOfTheTable]。列[IndexOfTheColumn]
///您可以用相同的方式设置DisplayMember和ValueMember。。
///我将combocell和combocolumn放在一起显示语法。
yourDataGridViewName.Controls.OfType()
.ElementAt(0.DisplayMember=“YourDisplay”;
yourDataGridViewName.Controls.OfType()
.ElementAt(0).ValueMember=“YourValue”;
关于第二个问题。。如果你问我,那么我更喜欢:为了控制“意外保存”,在行的末尾放一个buttonCell..当用户更改行上的内容时,应该单击save按钮..然后在ButtonClick方法中,可以将更改保存为普通的insert或update方法

这里只有两个区别

1-)您需要使用
Cell\u Click
事件,并确保使用
OfType()
方法检查按钮,而不是正常的
按钮\u Click
事件


2-)根据项目需要,您需要先获取DataGridView的
RowIndex
和/或
Cell Address()
,然后才能获取值并将其传递给SQLQuery

谢谢,这样做与您提到的方式类似。我认为if是
SqlCommandBuilder
的一种“更容易”的方式,但我没有找到它。@janolmayti你不能用commbuilder做任何事情,你也不需要;)如果我需要创建一个控件作为您的控件,那么我更喜欢这种方式:我创建一个表,其中包含整数(即您的组合框列的selectedindex no以及其他列的日期和id等)和crud(ins upd del)此表的过程..如果project_name必须具有某些属性,则为这些属性创建另一个表,并使用datareader将id/name从那里带到combobox(dreader更快)…如果project_name只需要名称和id,则我更喜欢创建字典并使用它设置dgv combocell的数据源(作为一个更安全、更快的选项,您总是更喜欢在Sql操作中使用datareader和存储过程…)在这些步骤之后,我可以将行值传递到存储过程,这比sqlcommandbuilder和query更简单、更安全