Hiding gridview rows takes two tries - c#

I created a gridview with textboxes in the footer for the insert function. I have the footer defaulted to hidden. I also added an 'Add' button to the first column of the header that I will use to show the footer. I also want this button to hide the gridview rows and the button itself, effectively keeping them from hitting the add button when they're already in insert mode, and bringing the footer to the top of the gridview.
(VS2008 C#)
protected void btnNewUser_Click(object sender, EventArgs e)
{
for (int i = 0; i < GridView2.Rows.Count; i++)
{
GridView2.Rows[i].Visible = false;
}
GridView2.ShowFooter = true;
GridView2.HeaderRow.FindControl("btnNewUser").Visible = false;
}
When I click the button the first time, the footer displays, but the rows and button stay visible. When I click the button a second time, the rows and button become hidden. How do I get this all to work in one click?
Edit: If I comment out GridView2.ShowFooter = true; it will hide the rows just fine. Is there some kind of a postback/refresh/databind, etc.happening when I show the footer?

Yes, changing the value of the ShowFooter property marks the gridview for rebinding.
The implementation looks as follows:
set
{
bool showFooter = this.ShowFooter;
if (value != showFooter)
{
this.ViewState["ShowFooter"] = value;
if (base.Initialized)
{
base.RequiresDataBinding = true;
}
}
}
A possible workaround could be to set to footer visibility instead. (And always have ShowFooter set to true)
GridView2.FooterRow.Visible = true/false;

Related

DataGridView not displaying changes to checkbox when application is launched

I have the following code that will create a checkbox column, insert as first column to the main data grid, and then loop through the rows to set the checkbox to checked. Basically, what I'm trying to do is add checkboxes that are checked by default when the application launches.
The issue is that when the application is started, the checkboxes remain untouched. I've added the ToolTip text below to see whether that takes effect, but no luck there.
I also added an event that will trigger the same code below (calling the same method), and it will refresh the grid with the checkboxes CHECKED.
DataGridViewCheckBoxColumn importSelectionColumn = new DataGridViewCheckBoxColumn();
importSelectionColumn.Name = "dataSelection";
importSelectionColumn.DisplayIndex = 0;
importSelectionColumn.HeaderText = "\u2611";
importSelectionColumn.Width = 35;
importSelectionColumn.Visible = true;
importSelectionColumn.FalseValue = false;
importSelectionColumn.TrueValue = true;
importSelectionColumn.HeaderCell.Style.Font = new Font(FontFamily.GenericSansSerif, 16f);
// Add column to grid:
mainDataGrid.Columns.Insert(0, importSelectionColumn);
// Set checkbox to true for all rows:
foreach (DataGridViewRow row in this.mainDataGrid.Rows)
{
row.Cells["dataSelection"].Value = true;
// Adding this just to see whether it's set when application starts.
row.Cells["dataSelection"].ToolTipText = "Testing";
}
mainDataGrid.RefreshEdit();
mainDataGrid.Refresh();
Make sure that the code that changes state is not being executed too early.
It should be executed after Loaded event of the container form, when all controls are loaded and ready for work.
Adding a check box control to your mainDataGrid can be done in DataBound event instead of on page load event.
Try to use below code on your page and check:
protected void mainDataGrid_DataBound(object sender, EventArgs e)
{
foreach (GridViewRow objRow in mainDataGrid.Rows)
{
TableCell tcCheckCell = new TableCell();
CheckBox chkCheckBox = new CheckBox();
tcCheckCell.Controls.Add(chkCheckBox);
objRow.Cells.AddAt(0, tcCheckCell);
}
}

Focus not setting on DataGridView on Button Preview KeyDown Event

Pressing Tab key on Button Refresh is setting focus on the dropdown list but I need to set focus on Checkbox column and first row of grid when the grid datasource is not null else the next control, however it is selecting the given cell only. I have set tabIndex property in sequence, please tell me where i am wrong, here is my code:
private void btnRefresh_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
if (grid.DataSource != null)
{
grid.Focus();
grid.CurrentCell = this.grid[1, 0];
grid.CurrentCell.Selected = true;
grid.BeginEdit(false);
}
else
{
btnCancel.Focus();
}
}
}
Have you seen this post?
Seems like your use of the index is of Grid[x,y].
Try
grid.Rows[1].Cells[0]
However, this wil select only the cell (first cell, second row by the way).
If you want to select the entire row, try
grid.Rows.First().Selected = True
Hope it helps.

Add buttons to datagridview in windows form

I want to add two buttons onto datagridview. Now they are on the right side. But I want to locate them on the left.
The other thing is I want to add an update event for "Edit" button. Is it
private void Edit_Click(object sender, EventArgs e)
{
}
Form code:
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'qDataSet.Metric' table.
// You can move, or remove it, as needed.
this.metricTableAdapter.Fill(this.qDataSet.Metric);
DataGridViewButtonColumn EditColumn = new DataGridViewButtonColumn();
EditColumn.Text = "Edit";
EditColumn.Name = "Edit";
EditColumn.DataPropertyName = "Edit";
dataGridView1.Columns.Add(EditColumn);
DataGridViewButtonColumn DelColumn = new DataGridViewButtonColumn();
DelColumn.Text = "Delete";
DelColumn.Name = "Delete";
DelColumn.DataPropertyName = "Delete";
dataGridView1.Columns.Add(DelColumn);
}
The image likes:
Thank you.
You seems to have design the datagridview from the designer.
You can use the wizard which allow to edit columns. There you'll add two columns (one for editing and the other for deleting). You can choose where you want to set those columns.
The text of the button is defined using the property "Text", you can also set the property "UseColumnTextForButton".
You can manage easily in the CellContentClickEvent the column and row which is clicked and then do the job.
If you want to manage access right (like allowing someone to editing and someone else to not editing) you can play with show/hide of this column.
See DisplayIndex
The zero-based position of the column as it is displayed in the associated DataGridView, or -1 if the band is not contained within a control.
EditColumn.DisplayIndex = 0;
DelColumn.DisplayIndex = 1;
You can't subscribe to the Edit button events directly.
So, the decision to subscribe to the CellClick event and check which are pressed
And yes, for columns position set DisplayIndex property
DataGridViewButtonColumn ButtonColumn = new DataGridViewButtonColumn();
ButtonColumn.Name = "Print";
ButtonColumn.HeaderText = "Print";
ButtonColumn.FlatStyle = FlatStyle.Popup;
ButtonColumn.DefaultCellStyle.ForeColor = Color.White;
ButtonColumn.DefaultCellStyle.BackColor = Color.CadetBlue;
ButtonColumn.Text = "Print";
ButtonColumn.UseColumnTextForButtonValue = true;
int columnIndex = 12; /*your column index number*/
if (dtGridTicket.Columns["Print"] == null)
{
dtGridTicket.Columns.Insert(columnIndex, ButtonColumn);
}
If you load the page column index hide so you use
dtGridTicket.Columns.RemoveAt(12);

How to add buttons to datagridview cells not entire column

How do you add a button to cells in a row and not the entire column in a datagridview?
I think Adrian's answer was close. Try something like this.
if ((string)table.Rows[0].Cells[0].Value == "I should be a button") {
// you can add formatting or values to the button before assigning it here
table.Rows[0].cells[0] = new DataGridViewButtonCell();
}
I think the best answer if found here:
Hide gridview button. All you need to do is to add a DataGridViewButtonCell where you want buttons, and DataGridViewTextBoxCell where you do not. The column has to be DataGridViewButton type.
See this similar post in SO, probably helps
adding control to gridview
In case Win Form, Check this MSDN post
Column Types in the Windows Forms DataGridView Control
OR this code project post ... though it gives example of adding a image button
DataGridView Image Button Cell
#tmax In that case you can probably put your button creation code in GridView_RowCreated event like below
void GridView_RowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.Header)
{
//Button creation code here
}
}
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
Button btn = new Button();
//btn attributes
dataGridView1.Rows[0].Cells[3].Value = new Button();
}
try something like this.
What I endded up doing was stacking a DataGridView on top of another one. I turned off the border, gridlines, and scrollbars. Then create dynamic button columns to match the main datagridview with only one row of buttons. Then I used the ColumnWidthChanged event handler to resize both the DataGridViews together. Anyway's this was my workaround for now.
DataGridViewButtonColumn dataGridViewButtonColumn = new DataGridViewButtonColumn();
dataGridViewButtonColumn.Name = "Select";
dataGridViewButtonColumn.HeaderText = "Select";
dataGridViewButtonColumn.ReadOnly = false;
dataGridView1.Columns.Add(dataGridViewButtonColumn);
After assigning data source to gridviewCTRL. you can add new column with button with below code.
DataGridViewButtonColumn startbtn = new DataGridViewButtonColumn();
startbtn.Name = "Action";
startbtn.Text = "Start";
startbtn.UseColumnTextForButtonValue=true;
int columnIndex = 6;
gridviewCTRL.Columns.Insert(columnIndex, startbtn);
This will add the button to each and every row at define column index.
if you want to render condition the AccessibleObject, then you can do something similar to below.
foreach (DataGridViewRow rowdata in gridviewCTRL.Rows)
{
// this is just an example in my case i am checking a previous column value
if (rowdata.Cells[5].Value=="XYZ")
{
rowdata.Cells[6] = new DataGridViewTextBoxCell();
}
}
This way you can dynamically render/ showing the control in the GridView in Winforms c#.
The above code simple update the cell with new cell. We can't remove button from the cell nor remove whole, so instead we can initial a new cell that will override the button visibility.
I am not sure if this will help but you can also consider using TableLayoutPanel.
Refer: Winforms TableLayoutPanel adding rows programmatically

How do I add a buttons to some (not all) of the columns in my DataGridView?

I'm trying to update this DataGridView object such that if a value == "bob" there will be a button in a column next to its name, otherwise I don't want any button to appear.
DataGridViewTextBoxColumn valueColumn = new DataGridViewTextBoxColumn();
DataGridViewButtonColumn buttonColumn = new DataGridViewButtonColumn();
buttonColumn.ReadOnly = true;
buttonColumn.Visible = false;
this.dgv.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
valueColumn,
buttonColumn,
});
//elsewhere...
if(value == "bob")
{
Button button = new Button()
{
Text = "null",
};
index = dgv.Rows.Add(value, button);
DataGridViewButtonCell buttonCell = dgv.Rows[index].Cells[2] as DataGridViewButtonCell;
buttonCell.Visible = true;
}
else
{
dgv.Rows.Add(value);
}
But, since I can't set Visible on a cell, this doesn't work. Is there a way to add a button to only the rows were Value == "bob"?
Here is a neat little hack that I've used before to accomplish this:
Instead of using a DataGridViewButtonColumn, use the DataGridViewTextBoxColumn and add a DataGridViewButtonCell where appropriate.
e.g.
private void button1_Click(object sender, EventArgs e)
{
// Iterate through each of the rows.
for (int i = 0; i < dgv.RowCount - 1; i++)
{
if (dgv.Rows[i].Cells[0].Value.ToString() == "bob")
{
// Here is the trick.
var btnCell = new DataGridViewButtonCell();
dgv.Rows[i].Cells[1] = btnCell;
}
}
}
In the example above, I have two DataGridViewTextBoxColumns and iterate through each of the rows on a button click event. I check the first column to see if it contains "bob" and if it does, I add a button in the column next to it. You can use this trick however you want (i.e. button clicks, RowsAdded event, CellEndEdit event, etc.). Experiment in different ways. Hope this helps someone!
There are two possibilities here, one ugly and one from MSDN.
The Ugly: Add a button to your DGV at runtime
Do the following:
- Add an unbound DataGridViewTextBoxColumn to your DGV. Note it's index value in your DGV; this is where you'll put your button.
- Use your DGV's CellFormatting event like so:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
if (e.ColumnIndex == 0) { // Assumes column 0 has the data that determines if a button should be displayed.
if (e.Value.ToString() == "bob") { // Test if a button should be displayed on row.
// Create a Button and add it to our DGV.
Button cellButton = new Button();
// Do something to identify which row's button was clicked. Here I'm just storing the row index.
cellButton.Tag = e.RowIndex;
cellButton.Text = "Hello bob";
cellButton.Click += new EventHandler(cellButton_Click);
dataGridView1.Controls.Add(cellButton);
// Your ugly button column is shown here as having an index value of 3.
Rectangle cell = this.dataGridView1.GetCellDisplayRectangle(3, e.RowIndex, true);
cellButton.Location = cell.Location;
}
}
}
When a user clicks the button the cellButton_Click event will fire. Here's some test code:
void cellButton_Click(object sender, EventArgs e) {
Console.WriteLine("Hello from row: {0}", ((Button) sender).Tag);
}
As you can see this isn't very refined. I based it on an even uglier sample I found. I'm sure you can modify it to suit your needs.
From MSDN: Roll your own (extend) DataGridViewButtonColumn that conditionally displays a disabled button.
For this option see How to: Disable Buttons in a Button Column in the Windows Forms DataGridView Control
Of course this option doesn't actually remove any buttons, only conditionally disables them. For your application however, this might be better.
You can handle cell painting on cell painting event:
private void dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if(e.RowIndex>=0 && e.ColumnIndex == indexOfButtonColumn && value[e.RowIndex] != "bob")
{
e.Paint(e.ClipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentForeground & ~DataGridViewPaintParts.ContentBackground);
e.Handled = true;
}
}

Categories