I had a Gridview which contains 3 columns , initially during form load i only two columns will be visible one column will be having data and other having checkbox.
i want when i check a checkbox in particular cell, corresponding to that checkbox the third column cell will be visible, i don't want to complete 3rd column to get visible on checking a check box ,Gridview is hardcoded only rows are dymanic (column1,column2 are set to visible and column 3 is set to invisible)
in below inmage when i m checking checkbox complete thried column is visible,which i don't want
can any one help me in this?
i tried below code but it is making 3rd column visible not, particular cell
public form1()
{
dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
}
void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.Columns[e.ColumnIndex + 1].Visible = true;
}
Well You can try RowCommand event for this but as i see you already have event created for checkbox ,Try to find row Index for particular row and then use Cell number (cell[2]) to find the control and assign its property as visible = false,
Here is the demo I've just tried. It seems to work OK. The whole idea is You can't hide a particular cell in DataGridView. However you can make it hidden as a normal GUI engine will use when it wants to hide any control/element (I think so). You just customize it to paint the cell with the BackgroundColor of your DataGridView. Of course, to make it work, it's not such easy. Here is the code for you:
//First, you have to be sure the whole third column is Visible.
//CellPainting event handler for your dataGridView1
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == 2)//This is the Column index you want to hide.
{
object o = e.RowIndex == -1 ? null : dataGridView1[e.ColumnIndex - 1,e.RowIndex].Value;
if (o!=null &&!(bool)o || e.RowIndex == -1 || e.RowIndex == dataGridView1.RowCount - 1)
{
e.Graphics.FillRectangle(new SolidBrush(dataGridView1.BackgroundColor), e.CellBounds);
if(e.RowIndex > -1) dataGridView1[e.ColumnIndex, e.RowIndex].ReadOnly = true;
e.Handled = true;
}
if (o != null && (bool)o)
{
dataGridView1[e.ColumnIndex, e.RowIndex].ReadOnly = false;
}
}
}
//CellContentClick event handler for your dataGridView1
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
UpdateThirdColumCell(e);
}
//CellContentDoubleClick event handler for your dataGridView1
private void dataGridView1_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
UpdateThirdColumCell(e);
}
private void UpdateThirdColumCell(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 1)//The column index of the CheckBox column
{
DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)dataGridView1[e.ColumnIndex, e.RowIndex];
cell.Value = cell.EditingCellFormattedValue;
dataGridView1.Invalidate();
if ((bool)cell.Value)
{
dataGridView1.CurrentCell = dataGridView1[e.ColumnIndex + 1, e.RowIndex];
}
}
}
//CellStateChanged event handler for your dataGridView1
private void dataGridView1_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
{
if (e.Cell.ColumnIndex == 2 && e.Cell.Selected)
{
dataGridView1.BeginEdit(false);
}
}
And that's all :)
Yeah ,actually we can't make invisible but i want to give an explianation about it in simple way.using
datagridview.rows(e.rowindex).cells[your column name]=true ;
using this it won't allow the user to enter the data in the textbox.if it is false then we can modify it/enter any text.
datagridview.rows(e.rowindex).cells[your column name].backcolour=color.gray/white/black;
using this we can fill color to a particular textbox which is to be painted when checkbox is true/false;
Related
How can I highlight the row and current cell in a datagridview differently?
I have SelectionMode set to CellSelect and MultiSelect set to False.
I want the whole row to be highlighted and the selected cell to be highlighted in a different color. Basically something like this:
I'm trying to use the CellEnter event to do so with this code:
dgvResult.SelectedRows[0].DefaultCellStyle.SelectionBackColor = Color.LightBlue;
dgvResult.SelectedCells[0].Style.SelectionBackColor = Color.Blue;
dgvResult.Refresh();
Unfortunately the first line seems to only work when Selection Mode is set to FullRowSelect and the second row only works when set to CellSelect.
What am I doing wrong here?
This is a little trickier than one may hope.
You need to either keep track of the colors you set to the cells or reset all each time.
The latter is more reliable imo.
The DGV is in DataGridViewSelectionMode.FullRowSelect.
Note: Resetting a DefaultCellStyle Color is done by setting it to Color.Empty.
Example:
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
foreach ( DataGridViewRow row in dataGridView1.SelectedRows)
row.DefaultCellStyle.SelectionBackColor = Color.Empty;
foreach ( DataGridViewCell cell in dataGridView1.SelectedCells)
cell.Style.SelectionBackColor = Color.Empty;
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.SelectionBackColor = Color.RosyBrown;
dataGridView1[e.ColumnIndex, e.RowIndex].Style.SelectionBackColor = Color.LightSeaGreen;
}
Other events should also work..
Upddate:
As Jimi noted instead of resetting before setting in the same click event one can use the CellLeave event paired with the CellEnter event to do the same. Seems to work fine from my tests:
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.SelectionBackColor = Color.RosyBrown;
dataGridView1[e.ColumnIndex, e.RowIndex].Style.SelectionBackColor = Color.LightSeaGreen;
}
private void dataGridView1_CellLeave(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.SelectionBackColor = Color.Empty;
dataGridView1[e.ColumnIndex, e.RowIndex].Style.SelectionBackColor = Color.Empty;
}
I need to trim the cells in the DataGridView when it's populated with data.
I can't figure out how to call the CellFormatting event from within the DataBindingComplete Event. Surely it's as simple as;
private void iCBOMHDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
iCBOMHDataGridView_CellFormatting();
}
I am doing something similar that might help. In my case, I am setting an inactive user's whole row to gray text, but it is still cell formatting:
dgvUsers.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.dgvUsers_CellFormatting);
this.Controls.Add(dgvUsers);
The lines above happen before you dgvUsers.Enabled = true; The grid has been loaded, but not displayed. Then the handler that gets called is:
private void dgvUsers_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataRowView row = dgvUsers.Rows[e.RowIndex].DataBoundItem as DataRowView;
if (row != null && row.Row.ItemArray[7].Equals("N"))
{
e.CellStyle.ForeColor = Color.Gray;
dgvUsers.Invalidate();
}
}
The main difference between the cell styling I do and yours is that I am not working with the actual values in the cells, just their styling.
Is there an DataGridView equivalent of ListBox's IndexFromPoint method? I need it so that I can select a given cell when it is right-clicked, which it doesn't seem to detect normally, though left-clicks do select the cell. When I was using a ListBox, I achieved this through use of the IndexFromPoint method, which is why I bring it up here.
Try using the CellContentClick event. Make sure you verify the RowIndex is greater than 0 to handle when a user right clicks on a column header.
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right && e.RowIndex >= 0)
{
dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
}
}
What is name of following area in DataGridView? Can I do something with this area (like changing caption)? Is there are events for this area?
That portion is called as TopLeftHeaderCell
Even datagridview provides you a property named TopLeftHeaderCell
You can change the content of that cell via following code
dataGridView1.TopLeftHeaderCell.Value = "abc";
To capture click event of that cell capture CellClick event and handle e.ColumnIndex = -1 and e.RowIndex = -1
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == -1 && e.RowIndex == -1)
{
//TopLeftHeaderCell clicked
}
}
If you want to use the RowHeaderCell try this
dataGridView1.Rows[0].HeaderCell.Value = "1";
this will allow you to show numbers like Row Number
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;
}
}