My code:
private void InitGrid(DataTable dataTable, ref DataGridView grid, bool resetColumns)
{
if (grid.Columns.Count > 0)
{
if (resetColumns)
{
grid.Columns.Clear();
grid.DataSource = null;
}
else
{
return;
}
}
DataGridViewColumn column;
grid.AutoGenerateColumns = false;
// apply entire data from table to grid.
grid.DataSource = dataTable;
// set column properties according to their type (combo, text, etc.)
foreach (DataColumn col in dataTable.Columns)
{
if (m_ColumnTypes[col.ColumnName].Equals("COMBO"))
{
// get query number to load specific column's data
string adminQuery = Server.LoadData("633", new List<string>() { col.ColumnName, m_TableFullName }).Rows[0][0].ToString();
column = new DataGridViewComboBoxColumn();
string queryParam = Controller.MainController.User;
switch (col.ColumnName.ToUpper())
{
case "FIELD1NAME":
(column as DataGridViewComboBoxColumn).DisplayMember = col.ColumnName;
(column as DataGridViewComboBoxColumn).ValueMember = "field1id";
break;
case "FIELD2NAME":
(column as DataGridViewComboBoxColumn).DisplayMember = col.ColumnName;
(column as DataGridViewComboBoxColumn).ValueMember = "field2id";
queryParam = string.Concat("select column_value from table(fn_mgr_workspaces('", Controller.MainController.User, "'))");
break;
case "PRIORITY":
(column as DataGridViewComboBoxColumn).DisplayMember = col.ColumnName;
(column as DataGridViewComboBoxColumn).ValueMember = col.ColumnName;
queryParam = "10";
break;
}
(column as DataGridViewComboBoxColumn).DataSource = Server.LoadData(adminQuery, new List<string>() { queryParam });
}
else
{
column = new DataGridViewTextBoxColumn() { AutoSizeMode = m_ColumnTypes[col.ColumnName].Equals("TAGS") ? DataGridViewAutoSizeColumnMode.Fill : DataGridViewAutoSizeColumnMode.AllCells, ReadOnly = true };
}
column.Name = col.ColumnName.ToUpper();
column.HeaderText = m_ColumnNameTranslations[col.ColumnName.ToUpper()];
column.DataPropertyName = column is DataGridViewComboBoxColumn ? (column as DataGridViewComboBoxColumn).ValueMember : col.ColumnName;
grid.Columns.Add(column);
}
// after setting columns. going over every row and trying to filter out the datasource of field2. this is where my problem is
foreach (DataGridViewRow dgvr in grid.Rows)
{
if (!dgvr.IsNewRow)
{
string wsId = dgvr.Cells["filed1id"].Value.ToString();
DataTable filteredData = ((dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DataSource as DataTable).Select("thefieldname = " + wsId).CopyToDataTable();
DataView dv = filteredData.DefaultView;
dv.Sort = "field2name";
(dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DataSource = null;
(dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DisplayMember = "field2name";
(dgvr.Cells["field2name"] as DataGridViewComboBoxCell).ValueMember = "field2id";
(dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DataSource = dv.ToTable();
}
}
}
(field names and some object names were scrambled for security purposes)
My problem:
The DataSource of field2 which is a ComboboxColumn does not change. It always shows me the entire data and not the filtered data that I try to set for it.
Even though I nullify it and re-set it to the filtered data, it doesn't work.
What I'm trying to achieve is that the DataSource in field2 column should be dependant on the data of field1 for each row of the grid.
I tried setting the datasource for the other columns and not setting it for field2 and then after that going over every row and setting the filtered datasource on field2 but it comes up completely empty as if the datasource set for every row hasn't worked at all.
I'm doing something wrong. How the hell do I do this?
The EditControlShowing event on the DataGridView will allow you to accomplish this.
Add an event handler to this method.
private void grid_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if ( grid.CurrentCell.ColumnIndex == dgvr.Columns["field2name"].Index )
{
// Get Combobox
ComboBox combo = e.Control as ComboBox;
// Get Other Column's Value
string wsId = grid.Rows[grid.CurrentCell.RowIndex].Cells["filed1id"].Value.ToString();
// Get Filtered Data Based Off Of Other Column's Value
DataTable filteredData = (combo.DataSource as DataTable).Select("thefieldname = " + wsId).CopyToDataTable();
DataView dv = filteredData.DefaultView;
dv.Sort = "field2name";
// Rebind
combo.DataSource = null;
combo.DisplayMember = "field2name";
combo.ValueMember = "field2id";
combo.DataSource = dv.ToTable();
}
}
Related
I have a dataview that contains a DataGridComboBoxColumn for one value. I set the options with a list of strings, and then loop through the rows to set the initial values of this column. I can debug after looping through and the value is there as I expect it, but in the UI my combo box is still empty. Am I missing something that will set the value in the UI or what am I doing wrong?
private void PrepareList() {
var dt = new DataTable {
Columns = {
new DataColumn("Style Number"),
new DataColumn("Description"),
new DataColumn("Department"),
}
};
foreach (var orderEntity in _fullList) {
foreach (var line in orderEntity.Lines) {
dt.Rows.Add(line.VendorItemNumber, line.Description, line.Department);
}
}
var view = new DataView(dt) {Sort = "Style Number asc"};
var distinct = view.ToTable(true, "Style Number", "Description");
dataGrid.DataSource = distinct;
var repo = new DepartmentRepository();
var departments = repo.GetDepartmentList();
var vendor = new DataGridViewComboBoxColumn {
DataSource = departments,
ValueType = typeof(string),
HeaderText = #"Department",
Name = "Department",
DataPropertyName = "Department"
};
dataGrid.Columns.Add(vendor);
foreach (DataGridViewRow row in dataGrid.Rows) {
var dtRow = dt.AsEnumerable().FirstOrDefault(r =>
r["Style Number"].ToString() == row.Cells["Style Number"].Value.ToString());
var dept = dtRow == null ? "" : departments.FirstOrDefault(
s => s.StartsWith(dtRow["Department"].ToString()));
row.Cells["Department"].Value = dept;
}
dataGrid.Refresh();
foreach (DataGridViewColumn column in dataGrid.Columns) {
column.SortMode = DataGridViewColumnSortMode.NotSortable;
}
}
dataGrid.DataSource = distinct;
this code It should be placed after:
dataGrid.Columns.Add(vendor);
this way:
dataGrid.Columns.Add(vendor);
dataGrid.DataSource = null;
dataGrid.DataSource = distinct;
Edited
For me it works perfectly as follows:
DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
column.Name = "new";
column.HeaderText = "New";
column.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
column.DisplayIndex = 2;
datagridview1.Columns.Add(column);
column.DataSource = columnDataSource;
datagridview1.DataSource = null;
datagridview1.DataSource = dataGridViewDataSource;
datagridview1.Refresh();
I wanna know how I can transform this to GridControl code instead of DataGridView.
foreach (DataGridViewRow row in (IEnumerable)this.dataGridView1.Rows)
{
Data.SomethingA item = new Data.SomethingA
{
item.ac = Convert.ToUInt32(row.Cells[5].Value.ToString())
};
item.ad = Convert.ToUInt32(row.Cells[2].Value.ToString()[7].ToString());
item.ab = row.Cells[1].Value.ToString();
item.az = row.Cells[3].Value.ToString();
item.ae = Convert.ToUInt32(row.Cells[4].Value.ToString());
item.aq = row.Cells[6].Value.ToString();
ABC.Add(item);
}
Thank you
I assume you're using DataTable as DataSource. Cast it back to DataTable and loop through rows of datatable
private void DoSomething()
{
DataTable table = (DataTable)grid.DataSource;
foreach (DataRow row in table.Rows)
{
Data.SomethingA item = new Data.SomethingA
{
item.ac = Convert.ToUInt32(row[5].ToString())
};
item.ad = Convert.ToUInt32(row[2].ToString()[7].ToString());
item.ab = row[1].ToString();
item.az = row[3].ToString();
item.ae = Convert.ToUInt32(row[4].ToString());
item.aq = row[6].ToString();
ABC.Add(item);
}
}
You can just set the AspxGridView.DataSource = to dataGridView1.DataSource, or even better just set the AspxGrid.DataSource to be whatever your underlying datasource is (DataTable etc.).
The AspxGrid has a property to Auto generate the columns from the datasource.
I'm having difficulty setting the header value for DataGrid rows.
My DataGrid is bounded to DataTable but the following code won't display the row's header for the first row. Any ideas?
Note: RowHeadersVisible = True
(Assume that my DataTable has at least 1 col and 1 row before reaching this code)
public new void ShowDialog()
{
dataGridView_replaceTable.Columns.Clear();
dataGridView_replaceTable.Rows.Clear();
dataGridView_replaceTable.DataSource = getDataTable(); <-- returns DataTable
dataGridView_replaceTable.Rows[0].HeaderCell.Value = "ROW HEADER 1";
// I expect to see the this string in the first row header - but it remians empty!
}
The code for adding rows and columns to the DataTable:
we have:
replaceTableValues DataTable
as class property.
public void addCol()
{
DataColumn column;
column = new DataColumn(string colName);
column.DataType = System.Type.GetType("System.String");
column.ColumnName = colName;
column.ReadOnly = false;
replaceTableValues.Columns.Add(column);
}
public void addRow()
{
DataRow row;
row = replaceTableValues.NewRow();
string[] arr = new string[numOfCols+1];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = ""; // fill row data as empty string
}
try
{
replaceTableValues.Rows.Add(arr);
}
catch (System.Exception ex)
{
updateReplaceVarErrorMsg(TABLE_EXCEPTION);
}
}
What i'm trying to achieve: (red text)
Image
Thanks.
You should use HeaderText property of Columns collection instead:
dataGridView_replaceTable.Columns[0].HeaderText="ROW HEADER 1";
You could also do this when you add your columns by using Caption property:
public void addCol()
{
DataColumn column;
column = new DataColumn(string colName);
column.DataType = System.Type.GetType("System.String");
column.ColumnName = colName;
column.Caption = "My header" // ASSIGN HEADERS HERE
column.ReadOnly = false;
replaceTableValues.Columns.Add(column);
}
grid.Columns[0].HeaderText = "Something special";
A basic way to add a column is:
int columnIndex = grid.Columns.Add("columnName", "Header Text");
I have a ComboBox with its DataSource set to an instance of a DataTable. When rows are added to the DataTable, they show in the ComboBox without additional code, but when a row is deleted, the ComboBox remains unchanged. A short summary of my code:
ComboBox selector = new ComboBox();
DataTable tbl = new DataTable();
PopulateTable()
{
DataRow row1 = tbl.NewRow();
row1["field1"] = 1;
row1["field2"] = "Some Text";
tbl.Rows.Add(row1);
DataRow row2 = tbl.NewRow();
row2["field1"] = 2;
row2["field2"] = "More Text";
tbl.Rows.Add(row2);
}
PopulateSelector()
{
selector.DisplayMember = "field2";
selector.ValueMember = "field1";
selector.DataSource = tbl;
}
RemoveRow()
{
tbl.Rows[0].Delete();
}
At this point, the ComboBox appears to be correct, but clicking it resets it to its previous data. The DataTable remains correct, deleting the row causes no problem in that instance, I just can't make the ComboBox reflect the changes.
Try this:
PopulateSelector()
{
selector.DataSource = null;
selector.DisplayMember = "field2";
selector.ValueMember = "field1";
selector.DataSource = tbl;
}
RemoveRow()
{
tbl.Rows[0].Delete();
PopulateSelector()
}
You can use a bindingsource inbetween the datatable and the combobox and call ResetBindings
how to set checkbox value false in datagridview one row
private void dgvTodaysPlan_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvTodaysPlan.CurrentCell is System.Windows.Forms.DataGridViewCheckBoxCell)
{
dgvTodaysPlan.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
try this
// Add a new Column (ComboBox)
DataGridViewComboBoxColumn colForeign = new DataGridViewComboBoxColumn();
colForeign = MyDB.CreateComboBoxColumn("SELECT subjno,subject FROM subject", "ComboForeign", "subject", "subjno");
colForeign.HeaderText = "Subject";
colForeign.Width = 120;
colForeign.DisplayStyle = 0;
this.dataGridView2.Columns.Insert(3, colForeign)
Use DataPropertyName to get the selected key column as in :-
this.dataGridView2.Columns[3].DataPropertyName = "subjno";
It appears that this would be much easier in VisualStudio - maybe??
And here is the routine to Create the Combobox Column - very messy compared with Delphi :-
public DataGridViewComboBoxColumn CreateComboBoxColumn(string strSQLSelect, string strColName, string strDisplay, string strValue)
{
// Returns the DataGridViewComboBoxColumn to be inserted
DataGridViewComboBoxColumn colComboColumn = new DataGridViewComboBoxColumn();
DataTable dtbElements = new DataTable();
MySqlDataAdapter dbaElements = new MySqlDataAdapter(strSQLSelect, conn);
// Set some parameters for the ComboBoxColumn
colComboColumn.Name = strColName;
colComboColumn.DisplayMember = strDisplay;
colComboColumn.ValueMember = strValue;
// Add the Elements
dbaElements.Fill(dtbElements);
colComboColumn.DataSource = dtbElements;
// Return the column
return colComboColumn;
}
If the userAddedRow flag is set to true, unset the flag;
userAddedRow = false; and set id to 0, valid because autoincremented id's from server starting from 1 :-
dataGridView1["bookno", e.RowIndex].Value = 0;
You should convert it into a datagridviewcheckbox and set its value to false.