I am trying to update the row increment number in a DataGridView in my WinForms application after deleting a row or rows. I have looked at sources and the all point on how to add the incrementing to a column in DataTable. My DataGridView is bound to my DataTable, and that is bound to a DataSet.
How I created by datatable:
DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
itemNumber.AutoIncrement = true;
itemNumber.AutoIncrementSeed = 1;
itemNumber.AutoIncrementStep = 1;
DataColumn article = new DataColumn();
article.ColumnName = "Article";
article.ReadOnly = true;
DataColumn description = new DataColumn();
description.ColumnName = "Description";
description.ReadOnly = true;
DataColumn type = new DataColumn();
type.ColumnName = "Type";
type.ReadOnly = true;
//add to datatable
dt.Columns.Add(itemNumber);
dt.Columns.Add(article);
dt.Columns.Add(description);
dt.Columns.Add(type);
Removing a row from the DataGridView
foreach (DataGridViewRow row in dgvView.SelectedRows)
{
dgvView.Rows.RemoveAt(row.Index);
}
If I have 5 rows, and delete one. I would like the increment values to start from the 1,2,3,4 etc...
Can someone point me on how to achieve this?
I can't think of an efficient way to do this, but here are some ideas that may work with small data sets.
Keep up with the values yourself
1) Don't define the column as an AutoIncrement column):
DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
//itemNumber.AutoIncrement = true;
//itemNumber.AutoIncrementSeed = 1;
//itemNumber.AutoIncrementStep = 1;
2) Handle the DataGridView.RowsAdded and DataGridView.RowsRemoved events and "reset" the values:
private void dgvView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
if (dgvView.Columns.Contains("ItemNumber"))
{
foreach (DataGridViewRow r in dgvView.Rows)
{
r.Cells["ItemNumber"].Value = r.Index + 1;
}
}
}
private void dgvView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
if (dgvView.Columns.Contains("ItemNumber"))
{
foreach (DataGridViewRow r in dgvView.Rows)
{
r.Cells["ItemNumber"].Value = r.Index + 1;
}
}
}
Regenerate the values by rebuilding the DataTable and rebinding to it
1) Define the helper method below:
private DataTable ResetAutoIncrementColumn(DataTable dt, string autoIncrementColumnName)
{
DataTable result = new DataTable();
DataColumn itemNumber = new DataColumn(autoIncrementColumnName);
itemNumber.AutoIncrement = true;
itemNumber.AutoIncrementSeed = 1;
itemNumber.AutoIncrementStep = 1;
result.Columns.Add(itemNumber);
dt.Columns.Remove(autoIncrementColumnName);
result.Merge(dt, true);
return result;
}
2) Call it at the appropriate time (e.g. after a series of deletes as in the original question):
dt = ResetAutoIncrementColumn(dt, "ItemNumber");
dt.Columns["ItemNumber"].SetOrdinal(0);
dgvView.DataSource = dt;
dgvView.Columns["ItemNumber"].DisplayIndex = 0;
If you are just looking for a visual row number
Also, if you are just looking to have a visual row number on the DataGridView (and you don't care about the value being present in the underlying DataTable), you can handle the DataGridView.RowPostPaint event as follows (pulled from https://stackoverflow.com/a/12840794/3085273):
private void dgGrid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
var grid = sender as DataGridView;
var rowIdx = (e.RowIndex + 1).ToString();
var centerFormat = new StringFormat()
{
// right alignment might actually make more sense for numbers
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
e.Graphics.DrawString(rowIdx, this.Font, SystemBrushes.ControlText, headerBounds, centerFormat);
}
Related
How can I select the first row of the data in the datatable? And display the content on a labelbox, and radiobuttons?
OleDbDataAdapter dAdap = new OleDbDataAdapter(command);
DataTable dTable = new DataTable();
dAdap.Fill(dTable);
foreach(DataRow row in dTable.Rows)
{
question = row["QUESTION"].ToString();
c1 = row["C1"].ToString();
c2 = row["C2"].ToString();
c3 = row["C3"].ToString();
c4 = row["C4"].ToString();
ans = row["ANSWER"].ToString();
}
lblQuest.Text = question;
btnA.Text = c1;
btnB.Text = c2;
btnC.Text = c3;
btnD.Text = c4;
I tried this code, but it only displays the last row. Also when I try to rerun the query. It didn't refresh/replace/overwrite the values, it only displays the last row of the first query.
edit:
i = 0;
x = 0;
lblQuest.Text = dTable.Rows[i].Field<string>(x);
btnA.Text = dTable.Rows[i].Field<string>(x + 1);
btnB.Text = dTable.Rows[i].Field<string>(x + 2);
btnC.Text = dTable.Rows[i].Field<string>(x + 3);
btnD.Text = dTable.Rows[i].Field<string>(x + 4);
Your issue is that your variables are being overwritten with each loop. Once the loop gets through the whole DataTable it ends with the last row and only displays that.
To get the functionality you want you will need to store the DataTable as a property instead of a local variable.
One approach from there is to keep track of the row you are currently viewing. Then when the next button is clicked just ++ that current number and reassign the values.
class YourClass
{
private DataTable dt { get; set; }
private int CurrentRow { get; set; }
private void SomeMethod()
{
OleDbDataAdapter dAdap = new OleDbDataAdapter(command);
dt = new DataTable();
dAdap.Fill(dt);
CurrentRow = 0;
AssignToRow();
}
private void AssignToRow()
{
var row = dt.Rows[CurrentRow];
lblQuest.Text = row["QUESTION"].ToString();
btnA.Text = row["C1"].ToString();
btnB.Text = row["C2"].ToString();
btnC.Text = row["C3"].ToString();
btnD.Text = row["C4"].ToString();
}
private void NextButton_Click(object sender, EventArgs e)
{
CurrentRow++;
AssignToRow();
}
}
Yeah cause the variable will get overridden on every iteration and you will end up having the values for only last iteration
If you want to select only first row values use dTable[0][ColumnIndex]
To load next row on button click do:
int currentRow = 0;
DataTable myDt;
private void LoadNextRow()
{
currentRow++;
myLabel.Text = myDt[currentRow]["MyColumn"].ToString();
}
private void OnButtonClick(....)
{
LoadNextRow();
}
How can I set a value into gridview column? The thing is the column was added manually, not from the database. What I want is when the checklist value was 1 the cek22 column got ticked and when value was 0 the cek22 column was unticked. I used devexpress.
Example of my code that I used:
public void abc()
{
//select query in here
gridControl1.DataSource = dt;
//iam adding a column here
dt.Columns.Add("cek22",typeof(bool));
}
If your column is added manually then your column is working in unbound mode. So, you can just use its unbound expression. If you want to update your checklist column from cel22 then you can use CellValueChanging event.
Here is example:
var table = new DataTable();
table.Columns.AddRange(new[]
{
new DataColumn("preferred", typeof(string)),
new DataColumn("checklist", typeof(int))
});
table.Rows.Add("Director Fury", 1);
table.Rows.Add("Maria Hill", 0);
gridControl1.DataSource = table;
gridView1.PopulateColumns();
var column = new GridColumn();
column.FieldName = "cek22";
column.UnboundType = UnboundColumnType.Boolean;
column.UnboundExpression = "[checklist]";
column.Visible = true;
gridView1.Columns.Add(column);
gridView1.CellValueChanging += (sender, e) =>
{
if (e.Column.FieldName == "cek22")
gridView1.SetRowCellValue(e.RowHandle, "checklist", e.Value);
};
Here is the result:
The DevExpress Grid works with DataSource. So manipulate your DataSource and populate this to your Grid. The GridView will show this data. So if you want a check field i would recommend you to extend your DataSource with a bool Property. I don't now which DataSource you are using but if there is any bool value devexpress automatically add a checkbox column for you. If you want to link your custom column to the bool value in your DataSource you need to set the FieldName Property of the Column to your PropertyName.
If your checklist Property is 0 your bool Property return false and vice versa. This would be the easiest solution i guess. Assumed your are using a IList as DataSource.
Small example:
public class MyDataSource()
{
public int Checklist { get; set; }
public bool Cek22
{
get { return Checklist == 1; }
}
}
private void ExplainADevExpressGrid()
{
List<MyDataSource> dataSource = new List<MyDataSource>();
dataSource.Add(new MyDataSource());
myGrid.DataSource = dataSource;
}
Alternatively, add the column as part of the data source and populate it conditionally.
private void Form1_Load(object sender, EventArgs e)
{
DataTable dataTable = GetDataTable(10);
gridControl1.DataSource = dataTable;
}
private DataTable GetDataTable(int rows = 1)
{
DataTable table = new DataTable("Table1");
table.Columns.Add("checklist", typeof(int));
table.Columns.Add("cek22", typeof(bool));
for (int i = 0; i < rows; i++)
{
DataRow row = table.NewRow();
row["checklist"] = i % 2 == 0 ? 0 : 1;
row["cek22"] = ((int)row["checklist"]) == 0 ? false : true;
table.Rows.Add(row);
}
return table;
}
I have a data table in a data grid view. I want to put an listbox/dropdown menu in a specific column and row. I have tried this but it doesn't work --
var column = new DataGridViewComboBoxColumn();
RunTimeCreatedDataGridView[1, 1].Value = RunTimeCreatedDataGridView.Columns.Add(column);
Here is how I populate the table--
public DataTable createGridForForm(int rows, int columns)
{
// Create the output table.
DataTable table = new DataTable();
for (int i = 1; i <= columns; i++)
{
table.Columns.Add("column " + i.ToString());
}
for (int i = 1; i < rows; i++)
{
DataRow dr = table.NewRow();
// populate data row with values here
ListBox test = new ListBox();
myTabPage.Controls.Add(test);
table.Rows.Add(dr);
}
return table;
}
And here is how I create the datagridview.
private void createGridInForm(int rows, int columns)
{
DataGridView RunTimeCreatedDataGridView = new DataGridView();
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
//DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
//ID_Column.Width = 200;
int positionForTable = getLocationForTable();
RunTimeCreatedDataGridView.BackgroundColor = Color.WhiteSmoke;
RunTimeCreatedDataGridView.Size = new Size(995, 200);
RunTimeCreatedDataGridView.Location = new Point(5, positionForTable);
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
}
You were right on track with your first code block... the problem was you were trying to add a column to a cell reference. If you want to add a column where all rows have a drop down, then do exactly what you were doing, but simply add the column instead of specifying a cell value, like this:
var column = new DataGridViewComboBoxColumn();
RunTimeCreatedDataGridView.Columns.Add(column);
Then, specify the datasource as you normally would for a combobox.
Alternatively, if you want a specific cell to have a different combobox, or only a single cell in the column to have one, you can create a separate one as shown here or here.
Edit: To add a combobox to a specific cell in the DataGridView, you would do something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DataGridView dgv = new DataGridView();
// add some columns and rows
for (int i = 0; i < 10; i++)
{
DataGridViewCell c = new DataGridViewHeaderCell();
dgv.Columns.Add("Column" + i, Convert.ToString(i));
}
for (int i = 0; i < 10; i++)
{
dgv.Rows.Add(new DataGridViewRow());
}
//create a new DataGridViewComboBoxCell and give it a datasource
var DGVComboBox = new DataGridViewComboBoxCell();
DGVComboBox.DataSource = new List<string> {"one", "two", "three"};
DGVComboBox.Value = "one"; // set default value of the combobox
// add it to cell[4,4] of the DataGridView
dgv[4, 4] = DGVComboBox;
// add the DataGridView to the form
this.Controls.Add(dgv);
}
}
I want my table size to fit the data grid view. The data grid view size is always the same but the table can change in amount of rows and columns.
Here is how I populate the table:
public DataTable createGridForForm(int rows, int columns)
{
// Create the output table.
DataTable table = new DataTable();
for (int i = 1; i <= columns; i++)
{
table.Columns.Add("column " + i.ToString());
}
for (int i = 1; i < rows; i++)
{
DataRow dr = table.NewRow();
// populate data row with values here
ListBox test = new ListBox();
myTabPage.Controls.Add(test);
table.Rows.Add(dr);
}
return table;
}
And here is how I create the datagridview:
private void createGridInForm(int rows, int columns)
{
DataGridView RunTimeCreatedDataGridView = new DataGridView();
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
//DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
//ID_Column.Width = 200;
int positionForTable = getLocationForTable();
RunTimeCreatedDataGridView.BackgroundColor = Color.WhiteSmoke;
RunTimeCreatedDataGridView.Size = new Size(995, 200);
RunTimeCreatedDataGridView.Location = new Point(5, positionForTable);
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
}
I am getting an error when trying this code:
//DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
//ID_Column.Width = 200;
the error says that the:
Index was out of range. It may not be negative and must be smaller than the size
this is it
for the width-
RunTimeCreatedDataGridView.AutoSizeColumnsMode=System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
and for the height --
totalRowHeight = RunTimeCreatedDataGridView.ColumnHeadersHeight;
foreach (DataGridViewRow row in RunTimeCreatedDataGridView.Rows)
totalRowHeight += row.Height;
If you add your datagrid to your tab control before get Columns[0] you don't get that error.
Your code should be like that:
DataGridView RunTimeCreatedDataGridView = new DataGridView();
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
ID_Column.Width = 200;
EDIT:
I add detailed lines to fill your DataGridView to it's container.
private void createGridInForm(int rows, int columns)
{
DataGridView RunTimeCreatedDataGridView = new DataGridView();
RunTimeCreatedDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
// fill the gridview to its container
DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
ID_Column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
RunTimeCreatedDataGridView.Dock = DockStyle.Fill;
}
following line can be used to fill extra space with a specific column in a data grid view
RunTimeCreatedDataGridView .Columns["column_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
if you set this property of all column to DataGridViewAutoSizeColumnMode.Fill then all column takes same width
I have created a table in code behind file dynamically:
The code for creating this table is like this:
protected void BindGridviewNew(Guid SubscriptionID)
{
pnlreapeter.Visible = true;
gridviewnew.Visible = true;
List<string> plannig = new List<string>();
var s = m.bussinesCollection.BussinesPlanning.GetSingleSubVersionTrueFalse(SubscriptionID);
if (s != null)
{
if (s.T1.Value)
{
plannig.Add("T1");
}
if (s.T2.Value)
{
plannig.Add("T2");
}
if (s.T3.Value)
{
plannig.Add("T3");
}
if (s.T4.Value)
{
plannig.Add("T4");
}
if (s.T5.Value)
{
plannig.Add("T5");
}
if (s.T6.Value)
{
plannig.Add("T6");
}
if (s.T7.Value)
{
plannig.Add("T7");
}
if (s.T8.Value)
{
plannig.Add("T8");
}
if (s.T9.Value)
{
plannig.Add("T9");
}
if (s.T10.Value)
{
plannig.Add("T10");
}
}
DataTable PlanningDate = m.bussinesCollection.BussinesPlanning.GetRowOfPlanningDate(SubscriptionID);
DataTable Percentage = m.bussinesCollection.BussinesPlanning.GetAllStudentsForProgressForDocentNew(SubscriptionID);
DataTable dt = new DataTable();
DataRow newrow;
newrow = dt.NewRow();
DataRow Hiddenfield;
Hiddenfield = dt.NewRow();
DataRow percentage;
percentage = dt.NewRow();
int count = plannig.Count;
for (int j = 0; j < count; j++)
{
dt.Columns.Add(plannig[j], typeof(string));
string pl = plannig[j];
string c = pl.Substring(pl.Length - 1, 1);
int x = Convert.ToInt32(c);
DataRow dr = PlanningDate.Rows[0];
DateTime date = DateTime.Parse(dr[x-1].ToString());
newrow[plannig[j]] = date.ToShortDateString();
HiddenField hf = new HiddenField();
Hiddenfield[plannig[j]] = x;
DataRow dr1 = Percentage.Rows[0];
LinkButton link = new LinkButton();
link.Text = dr1[x].ToString();
percentage[plannig[j]] = (System.Web.UI.WebControls.LinkButton) link;
}
dt.Rows.Add(newrow);
dt.Rows.Add(percentage);
// dt.Rows.Add(Hiddenfield);
gridviewnew.DataSource = dt;
gridviewnew.DataBind();
}
The problem here is,as in screen shot I am trying to get link-buttond but the column type is string so that it shows "System.Web.UI.WebControls.LinkButton"
The table I want is like:
T1 | T2 | T3
3/01/2012| 3/03/2012| 3/05/2012
100 | 50 | -
where on clicking on 100 or 50 a new popup should be displayed.
Can any one help me to create this row..?
You can not add a LinkButton to a DataTable. What you should do is bind the DataTable to the GridView, and then manually add a new row to the grid view with the link buttons, I guess in the RowDataBound event, or if there is going to be just one row with link buttons, you can add a footer to the grid view.
Check this link How to programmatically insert a row in a GridView?