I have a multi column datatable like this,
datatable
I'm loading it to a combobox.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
datatable osdat = Loaddatatable();
postOScomboBox2.DataSource = osdat;
postOScomboBox2.DisplayMember = "Product";
postOScomboBox2.ValueMember = "Product";
postOScomboBox2.SelectedIndex = -1;
}
Instead of just showing p1,p2 the combobox is also showing two extra empty rows.
Same happens if i load the p1 column, 1 empty row is shown in combobox. Does display member have any property to check empty values and load only filled ones or any other way to achieve the same?
You can filter your table using methods from System.Linq.
datatable osdat = Loaddatatable();
var filteredTable = osdat.AsEnumerable()
.Where(row => row.Field<String>("Product") != null).CopyToDataTable();
postOScomboBox2.DataSource = filteredTable;
postOScomboBox2.DisplayMember = "Product";
postOScomboBox2.ValueMember = "Product";
postOScomboBox2.SelectedIndex = -1;
You have two empty values in product column and one empty value in p1 column. Combobox works as expected. If you want to filter these values filter your datasource instead. it's not a responsibility of combobox to filter datasource.
Here is a link how to filter datatable from empty values:
Filtering a empty string in DataTable
Related
In C# WinForms I have two DataGrids displaying tabular data. First display all rows, second one is supposed to display filtered set of these rows. I need to build filtered view on my BindingList view instance. This view needs to be updated, once underlying list is changed.
I've tried to build new BindingList instance with LINQ and Where
but the filtered is not updated when underlying myList is changed.
var filtered = new BindingList<Clip>(myList.Where<Clip>
(
c => c.participant.Contains(id)
).ToList<Clip>());
How can I do this?
Thanks
BindingList<T> doesn't support filtering (not directly, at least), so I propose to substitute your BindingList with a DataTable. DataView supports filtering and the filtered data is just a custom subset of the same DataTable.
In the example, two BindingSource classes are use to bind the same DataTable to two DataGridView controls.
One of the BindingSource class is bound to a filtered DataView of the DataTable, using the DataView.RowFilter property, an Expression which accepts a subset of SQL-like commands.
Here, the second DataGridView.DataSource is set to the BindingSource that has its DataSource linked to the filtered DataView.
The filter is defined using a specific value ("Value A1") of the second Column (Column1).
You can see in the visual sample that the two DataGridView control update their cells values when the cells' values of both the DataGridViews are changed.
Also, the filter is active on the second DataGridView: the rows are filtered when the filtered Column(s) values change.
To test this behaviour, add 2 DataGridView controls to a Form, add a Button (here, named btnBind) and subscribe to the Click event with the btnBind_Click handler.
private BindingSource dgvBindingSource1 = null;
private BindingSource dgvBindingSource2 = null;
private DataTable dt = null;
private void btnBind_Click(object sender, EventArgs e)
{
FillData(3, 3);
dgvBindingSource1 = new BindingSource(dt, null);
DataView dv = dt.AsDataView();
dv.RowFilter = "Column1 = 'Value A1'";
dgvBindingSource2 = new BindingSource(dv, null);
dataGridView1.DataSource = dgvBindingSource1;
dataGridView2.DataSource = dgvBindingSource2;
}
private void FillData(int cols, int rows)
{
dt = new DataTable("TestTable");
dt.Columns.AddRange(Enumerable.Range(0, cols)
.Select(i => new DataColumn("Column" + i.ToString(), typeof(string))).ToArray());
for (int r = 0; r < rows; r++) {
dt.Rows.Add(Enumerable.Range(0, cols)
.Select(n => $"Value {(char)('A' + r)}" + n.ToString()).ToArray());
}
}
I Have requirement to fill the datagridview row by row . i.e. if 3rd row is currently selected then data needs to be filled in 3rd row (my query returns always single row ) . same for every row.
some what like
DataTable dt = new DataTable();
dataadapter.Fill(dt);
dataGridView1.Rows[index].DataSource = dt; (just a hunch, but not working)
(instead of ) //dataGridView1.DataSource = dt;
hope that I made my requirement clear to you
Is their any way to accomplish it ....
Thanks in advance....
If your query returns a single row then you just have to fill the columns with correct values from your query:
dataGridView1.Rows[rowIndex].Cells["ColumnName"].Value =
dt.Rows[0]["ColumnNameInDataTable"].ToString();
Your grid will not be bound to the data this way. But it will fill the columns in the current row like you've asked.
I don't think this is possible directly,
You could use a List with a certain amount of empty objects and bind this List to your DataGridView... Then you would have empty Rows to work with. You can then fill single rows of the List with data and update the binding.
I also think you need a BindingSource and not a DataTable in this case...
Something like this:
private List<YourObject> gridData; // List
private BindingSource bindingSource;
public void Init()
{
this.gridData = new List<Anything>();
//prefill list, in this case we want to have 100 empty rows in DataGrid
for (var i = 0; i < 100; i++)
{
this.gridData.Add(new YourObject());
}
this.bindingSource.DataSource = this.gridData;
}
public void UpdateRow(int row)
{
this.gridData[row] = (from .. in select ...).FirstOrDefault(); // your query
}
I am capable of filling ComboBox with one Datatable. But i am not able to fill the same combobox with another datatable during runtime. First dataTable and Second Datatable contains different Data with Same Columns.
dtOne= abcd.RetrivData();
cnsmNm.DataSource = dtOne;
cnsmNm.DisplayMember = "One_Name";
cnsmNm.ValueMember = "One_Id";
second datatable
dtSecond= efgh.RetrivData();
cnsmNm.DataSource = dtSecond;
cnsmNm.DisplayMember = "One_Name";
cnsmNm.ValueMember = "One_Id";
You can use DataTable.Merge method. Like this:
dtOne.Merge(dtSecond);
cnsmNm.DataSource = dtOne;
I have a datagridview which has multiple text columns and a single comboboxcolumn. I need to specify a datasource for the iems of the comboboxcolumn and another datasource for the other text columns. I have tried the following sample code but it does not work.
dgv1.DataSource = DataSet1.Tables[0];
string[] managerList = Array.ConvertAll(DataSet2.Select(), row => (string)row[0]);
comboboxcolumn1.DataSource = managerList;
The managerList array has the entries that are to be populated into the combobox but they never show up.
Is that so that I can not have a separate datasource for a comboboxcolumn and its parent datagridview?
Thanks in advance.
I have checked with the following code and it works fine
string[] arr = "This Should Get Displayed".Split(); //managerList in your case
dataGridView1.DataSource = MyData(false);
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).DataSource = new BindingSource(arr, null); // Bind to the column of grid
Can you try assigning it as referencing it as a column of your datagridview.
This displays the text split on space in my combobox.
When you are using string array no need to specify Display and Value member for the column
EDIT
If you have a DataTable you can also do it in this fashion
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).DataSource= datatable;
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).DisplayMember="columnname";
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).ValueMember="columnname";
I have a DataGridView which takes values from the DB. Now I want to print out only the Selected Items which user has selected from the UI. This is what I did if the user wants to print out whole table in DataGridView:
var dataTable = dataGridView1.DataSource as DataTable;
Now I am trying to use the SelectedCells property in DataGridView. Cant get it though :-(
var selecteditems = dataGridView1.SelectedCells as DataTable;
What I am doing wrong here? All I want is to put my selected cells into a DataTable.
DataGridView.SelectedCells returns to you a collection, not a DataTable unfortunately.
If you want output as a DataTable, you could clone the structure of the table. Then, iterate through the SelectedCells collection.
Something like:
DataTable selected = dataTable.Clone();
for (int i = 0; i < dataGridView.SelectedCells.Count; i++)
{
DataRow newRow = selected.NewRow();
// may have to format below value
datarow["column"] = dataGridView.SelectedCells[i];
selected.Rows.Add(newRow);
}
Shoudnt be the second last line something like this:
newRow["column"] = dataGridView.SelectedCells[i];