I have a DataGridView in winforms, that contains a combobox column. The gridview is filled programmatically, and it is empty at start. "list" is a list containing custom objects. Value1/2/3 are unique to each row.
int[] array = new[] {value1,value2,value3}
for (int i = 0; i < list.Count; i++)
{
DataRow newrow = MyDataTable.NewRow();
newrow["idColumn"] = list[i].Customer_id;
newrow["dateoforderColumn"] = list[i].Customer_date;
newrow["commColumn"] = list[i].Customer_comment;
// This is what I want, and can't get to work.
newrow["comboColumn"] = array;
// I have also tried (newrow["comboColumn"] as DataGridViewComboColumn).DataSource
// but it didn't work either.
MyDataTable.Rows.Add(newrow);
}
How can I populate a freshly created combobox cell? Also, I need to do it within the for loop, because I need the index to get the data.
From the look of your code you just have one array of values that you need to set. In this case you only need to set it once for the column, not for every row, i usually do this in the constructor or before populating rows.
//Clear any junk items that may have been there from the designer or previous view
((DataGridViewComboBoxColumn)MyDataTable.Columns["comboColumn"]).Items.Clear();
//Add you new values
((DataGridViewComboBoxColumn)MyDataTable.Columns["comboColumn"]).Items.AddRange(array);
Then to set the value of the new row's cell
//Set value to be selected in new row
newrow["comboColumn"] = list[i].Customer_value;
Related
Is there any way to remove "columns" from an ArrayList?
I got this site up and running before attempting populating my DropDownLists from txt files so I hard-typed each value in. Now I've made an ArrayList from each DropDownList so I can display those lists in DataGridView on the site. The only issue is that "Enabled" and "Selected" show up as columns and I cannot seem to remove the column in the ArrayList, or specify which columns to bring in when creating the ArrayList, or GridView using GridView.Columns.Remove(); because the integers 0 or 1 or 2 don't seem to correspond with anything and the site doesn't run and I can't specify a string as the column title for what to remove.
The DataGrids show up with columns as |Enabled|Selected|Text|Value|
Here's the code for this piece as it stands (You can see what I've tried out and that didn't work that I've commented away):
// Create ListArrays from DropDownLists
ArrayList BuildingList = new ArrayList(Building.Items);
ArrayList DepartmentList = new ArrayList(Department.Items);
//Building.Items.Remove("Enabled");
//Building.Items.Remove("Selected");
// Populate Building GridView
BuildingGrid.DataSource = BuildingList;
BuildingGrid.DataBind();
//BuildingGrid.Columns.Remove;
//BuildingGrid.Columns[0].Visible = false;
// Populate Department GridView
DepartmentGrid.DataSource = DepartmentList;
DepartmentGrid.DataBind();
//DepartmentGrid.Columns[0].Visible = false;
//DepartmentGrid.Columns[1].Visible = false;
I would just go ahead and create a simple 2d array in a txt file with fields for "Value" and "Text" so the DropDownList will pull it in properly, but I can't figure that out either without being terribly inefficient and confusing.
Any help would be appreciated. Thanks.
So, here's the solution I ended up at. I finally figured out how to extract everything from a txt file, and place it into the grid the way I wanted to.
// Populate Department GridView
// get all lines of csv file
string[] BuildingString = File.ReadAllLines(Server.MapPath("Content/BuildingsCSV.csv"));
string[] DepartmentString = File.ReadAllLines(Server.MapPath("Content/DepartmentsCSV.csv"));
// create new datatable
DataTable BuildingTable = new DataTable();
DataTable DepartmentTable = new DataTable();
// Building Table
// get the column header means first line
string[] tempbuild = BuildingString[0].Split(',');
// creates columns of gridview as per the header name
foreach (string t in tempbuild)
{
BuildingTable.Columns.Add(t, typeof(string));
}
// now retrive the record from second line and add it to datatable
for (int i = 1; i < BuildingString.Length; i++)
{
string[] t = BuildingString[i].Split(',');
BuildingTable.Rows.Add(t);
}
// Department Table
// get the column header means first line
string[] tempdept = DepartmentString[0].Split(',');
// creates columns of gridview as per the header name
foreach (string t in tempdept)
{
DepartmentTable.Columns.Add(t, typeof(string));
}
// now retrive the record from second line and add it to datatable
for (int i = 1; i < DepartmentString.Length; i++)
{
string[] t = DepartmentString[i].Split(',');
DepartmentTable.Rows.Add(t);
}
// assign gridview datasource property by datatable
BuildingGrid.DataSource = BuildingTable;
BuildingGrid.DataBind();
BuildingGrid.Rows[0].Visible = false;
DepartmentGrid.DataSource = DepartmentTable;
DepartmentGrid.DataBind();
DepartmentGrid.Rows[0].Visible = false;
foreach (DataRow drb in BuildingTable.Rows)
{
BuildingDrop.Items.Add(new ListItem(drb[0].ToString(), drb[1].ToString()));
}
foreach (DataRow drd in DepartmentTable.Rows)
{
DepartmentDrop.Items.Add(new ListItem(drd[0].ToString(), drd[1].ToString()));
}
I am trying to populate a datagridview combobox column with comboboxcells in winforms where each row has a different collection derived from the nested list within the dictionary, the dictionary works fine when i iterate over it and get its objects and their string values, however every different combination i have exhausted to populate the combobox cells on form load has failed. Is it possible? I have found other posts where they use cellclick events etc. I prefer to populate on form initialization.
//this works
public void create datatable()
{
DataGridViewComboBoxColumn Data_CmBx_Col_ObjectType = new DataGridViewComboBoxColumn();
Data_CmBx_Col_FamilyType.Name = _ADD_OBJECT_TYPE;
Data_CmBx_Col_FamilyType.HeaderText = _ADD_OBJECT_TYPE;
dataGridView.Columns.Insert(6, Data_CmBx_Col_ObjectType);
//pop combobox, the dictionary works
int i = 0;
foreach (KeyValuePair<object, List<objectType>> objectAndType in combined_Dictionary)
{
i++;
if (rowIndex <= combined_Dictionary.Count)
{
CreateCustomComboBoxDataSouce(i, objectAndType.Value);
}
}
//Bind dataGridView to a datatable
dataGridView_Family.DataSource = data;
}//end method
//method is called and fails with index out of range error collection
private void CreateCustomComboBoxDataSouce(int row, List<objectAndType> type) //row index ,and two parameters
{
DataGridViewComboBoxCell comboCell = dataGridView_objectAndType[6, row] as DataGridViewComboBoxCell;
comboCell.DataSource = new BindingSource(type, null);
}//end method
The index is zero based, so it must be strictly less than its count
if (rowIndex < combined_Dictionary.Count) // not <= but without =
So, I have a DataGrid, that I want to manipulate programmatically a lot.
string[] values = new string[something.Count];
for (int i = 0; i < somethingElse.Count; i++)
{
if (condition)
values[i] = Data[i].ToString();
else
values[i] = "";
}
var style = new System.Windows.Style(typeof(DataGridRowHeader));
style.Setters.Add(new Setter(DataGridRowHeader.ContentProperty, Data[0].ToString()));
MyGrid.Items.Add(new DataGridRow()
{
HeaderStyle = style,
Item = values
});
This I do in a loop and I am able to fill in my grid with all the data I need.
Later, I am able to access cells, edit them, take their values, whatever I want and need.
However, when user wants to use the grid as you would in MS Excel, the cells are not editable.
So I went the other way and created a :
ObservableCollection<ObservableCollection<string>> gridData = new ObservableCollection<ObservableCollection<string>>();
//*** ... *** the gridData is filled in the same way, you can imagine
MyGrid.ItemsSource = gridData;
This does fill in the data perfectly the same way, more than that, the data are now editable.
But my custom row headers disappeared.
I need them, also, I do not think I want to use binding for row header values.
Can the first approach be somehow modified to still be editable, but rows with data being filled the very same way?
I eventually solved this combining both the abovementioned approaches.
First, I generate ObservableCollection<ObservableCollection<string>> dataCollection, fill it with data.
Next I generate an ObservableCollection<DataGridRow> rowCollection collection.
In my declarative part of the loop from the first approach, that you can see in the question, I do this
rowCollection.Add(new DataGridRow()
{
HeaderStyle = style,
Item = dataCollection[i] //for the corresponding iteration element
});
This all ends up when setting
MyGrid.ItemsSource = rowCollection;
Till now (very little time of testing), this seems to be what I was looking for, hope it might help someone else aswell.
I have used the GridView inside the ListView. I want to dynamically change a cell value. For example, there is a column named "Time", I wanna to change this value when something happens. I can find and get the cell (e.g od.Time as in following codes), but can not change its value. Some codes like this where ObjectData is the class for all ListView columns.
for (int i = 0; i < 5; i++)
{
ObjectData od = (ObjectData)objectListView.Items[i];
if (od.UserName == "Tom")
{
od.Time = DateTime.Now.ToString();
}
}
If the your listview is bound to a data source you'll need to change the data source's data, not the listview's contents. It should then update the listview.
I have a DataGridView that has MultiSelect = true. After the user selects different cells from different rows how can I get the value of all the selected cells?
You can iterate over SelectedCells.
foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
{
MessageBox.Show(cell.Value.ToString());
}
You asked only for the value, but you probably also want to know the row and the column of the cell otherwise the value could be meaningless. You can access these also on the cell object.
foreach -
DataGrid.SelectedCells
More info on the SelectedCells Property can be found at http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.selectedcells.aspx
The SelectedCells collection is inefficient with large selections in DataGridView. There is a method you can use to get the count of the selected cells. iterate based on that and it'll be faster.
for (int i = 0; i < grid.GetCellCount(System.Windows.Forms.DataGridViewElementStates.Selected); i++)
{
string val = grid.SelectedCells[i].Value;
}