DevExpress Grid, Bool rows change not reflect immediatly - c#

I have a DX grid view and it has 2 bool columns. My purpose is when I check for ex 2nd row in column1, column2 2nd must be changed immediatly, but not. It changes after clicking another row. Here is my rowcellvaluechanged event code :
void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
{
//button1.PerformClick();
if (e.Column.Name == "col1")
{
var x = gridView1.GetRowCellValue(e.RowHandler, col1);
gridView1.SetRowCellValue(e.RowHandler, col2, x);
}
}
I looked for in DX website and there is no solution. How can I handle on it ?

You can use the GridView.PostEditor method to immediately pass the changed value from the editor into the Grid's underlying data source. The best place for doing this is the EditValueChanged event of real cell editor. You can handle this event as follows:
gridView1.PopulateColumns();
var checkEdit = gridView1.Columns["Value1"].RealColumnEdit as RepositoryItemCheckEdit;
checkEdit.EditValueChanged += checkEdit_EditValueChanged;
//...
void checkEdit_EditValueChanged(object sender, EventArgs e) {
gridView1.PostEditor();
}
Then you can implement all needed dependencies:
gridView1.CellValueChanged += gridView1_CellValueChanged;
//...
void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e) {
if(e.Column.FieldName == "Value1")
gridView1.SetRowCellValue(e.RowHandle, gridView1.Columns["Value2"], e.Value);
}

The Grid posts an editor value when you switch to another cell. To force it, call the PostEditor method. But, in this case, you will need to use the EditValueChanged event of the active editor. To get it, use the ActiveEditor property. To catch the moment, when an editor is created, use the ShownEditor event.
gridView1.ShownEditor += gridView1_ShownEditor;
private void gridView1_ShownEditor(object sender, EventArgs e) {
GridView view = (GridView)sender;
view.ActiveEditor.EditValueChanged += editor_EditValueChanged;
}
private void editor_EditValueChanged(object sender, EventArgs e) {
if (!gridView1.FocusedColumn.Name == "col1")
return;
gridView1.PostEditor();
var x = gridView1.GetRowCellValue(e.RowHandler, col1);
gridView1.SetRowCellValue(e.RowHandler, col2, x);
}

Related

Automatic insertion of rows to DataGrid View without using a timer in Winforms

A row is to be automatically added in a datagridView of Winforms according to value changes in a text box.
A text box (textBox1) is used in the form to input the value. With the change in the value a row is to be inserted in the datagridview (dataGridView1)
I have used the following code for implementing the same,
private void timer1_Tick(object sender, EventArgs e)
{
int value;
value = Convert.ToInt32(textBox1.Text);
if(value == 2)
{
string[] row1 = {"Value is 2"};
dataGridView1.Rows.Add(row1);
}
}
The result I was expecting to get was a single row inserted in the dataGridView1.
I am getting the same row inserted a number of times since the code is running continuously inside the timer, timer1.
Can anyone help me with getting the expected result?
Can it be done without using a timer?
The usual approach would be to subscribe to the TextBox.TextChanged event:
//maybe in the form constructor
textBox1.TextChanged += HandleTextChanged;
Then you would need to implement a method HandleTextChanged somewhat like this (in the same class):
private void HandleTextChanged(object sender, EventArgs e)
{
if(int.TryParse(textBox1.Text, out var number))
{
if(number == 2)
{
string[] newRow = { "Value is 2" };
dataGridView1.Rows.Add(newRow);
}
}
}
For further information on events in WinForms, I propose you have a look at the documentation on learn.microsoft.com. Generally speaking WinForms is event-driven, so it's definitely useful to get used to the concept.
If you want to insert a new row according to the change in TextBox, you can use TextChanged event.
You delegate will be called each time the text is changed.
private void textbox_TextChanged(object sender, EventArgs e)
{
// place your code here for adding a row.
}
The textbox has a multitude of events, which you can inspect in the designer, by clicking it and selecting in the Properties window the yellow flash on the top.
if you want to add your textbox always as row when you finsihed editing the textbox,
use the apropiate event (Leave maybe) and add your row in there.
You could have your timer event tick once and then disable it:
private void timer1_Tick(object sender, EventArgs e)
{
int value;
value = Convert.ToInt32(textBox1.Text);
if(value == 2)
{
string[] row1 = {"Value is 2"};
dataGridView1.Rows.Add(row1);
}
timer1.Enabled = false; //<--disable timer1 once your job is done
}

How to check all selected check boxes when you check one in C# datagridview

I'm pretty new to C# development, but here goes. I'm working on a plugin for Autodesk revit, which creates a windows form with a datagridview on it which gets populated with several checkbox columns when the form loads. What I would like to do is select multiple checkbox cells, and check one of the selected boxes in order to check all selected boxes.
I have tried using a SelectionChanged event handler to store the selected sells in another variable. Then I'm trying to use CellValueChanged in order to set all those cells to the new value
DataGridViewSelectedCellCollection selCells = null;
private void revDataGridView_SelectionChanged(object sender, EventArgs e)
{
selCells = revDataGridView.SelectedCells;
}
private void revDataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
foreach(DataGridViewCell cell in selCells)
{
cell.Value = revDataGridView[e.ColumnIndex, e.RowIndex].Value;
}
}
My problem is that as soon as I click on the one cell, it resets the DataGridView.SelectedCells to that one cell and I lose the previous selection. Any help would be greatly appreciated!
EDIT: I solved this by storing the selection in another variable (selCells) and using a combination of the CellMouseUp, CellMouseDown, and CellValueChanged event handlers:
private void revDataGridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (selCells != null && selCells.Count>1)
{
revDataGridView.EndEdit();
selCells = revDataGridView.SelectedCells;
}
else if(selCells !=null && selCells.Count == 1)
{
selCells = revDataGridView.SelectedCells;
revDataGridView.EndEdit();
}
}
//when a value is changed, apply change to all selected cells
private void revDataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
foreach(DataGridViewCell cell in selCells)
{
if (cell.ReadOnly == false)
{
cell.Value = revDataGridView[e.ColumnIndex, e.RowIndex].Value;
cell.Selected = true;
}
}
}
//clear selection upon mouse button down
private void revDataGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
revDataGridView.ClearSelection();
}

be aware of insert delete and update data into gridview in c#

I have a grid view that has a column called Amount .I have a textbox that shows the sum of amount column in gridview ,but i need to be aware when items in gridview are inserted changed and deleted because i need to update the textbox
Has anyone handled such a scenario. I would like to know which datagrid event I should be using,
I am using windows form application
Best regards
You can make use of RowsRemoved, RowsAdded and CellValueChanged events.
Updated
You can use these assuming your user is only adding and deleting 1 row at a time. also added a method with a linq statement to sum up your amount and assign it to the textbox.
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex.Equals(dataGridView1.Columns["Amount"].Index))
{
UpdateTotal();
}
}
private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
UpdateTotal();
}
private void dataGridView1_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
{
UpdateTotal();
}
private void UpdateTotal()
{
textBox1.Text = (dataGridView1.Rows.Cast<DataGridViewRow>()
.Sum(t => Convert.ToInt32(t.Cells["Amount"].Value))).ToString();
}

How to check which cell is clicked in a datagridview

In the first column of my datagridview, I have checkboxes and I want to fire an event each time the status of the checkbox is changed. I thought of using the cellcontentclick event, casting the sender object to datagridviewcell and checking by its column index. But I found out that the sender object is a datagridview object. So, how to perform the desired operation?
To handle CheckBoxCell value changed you have to use this event CellValueChanged. Sender in events will always be the control that raised the event. To have more information about what happend you need to take a look into EventArgs.
Back to handling CheckBoxCell do this:
private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
var dgv = sender as DataGridView;
var check = dgv[e.ColumnIndex, e.RowIndex].Value as bool?;
if (check.HasValue)
{
if (check)
{
//checked
}
else
{
//unchecked
}
}
}
Hope this helps :)
There are many methods
One Method is :
You can take a hidden field or viewstate on page in which you can store row id when click occured by javascript and then in code behind get that hiddenfield value.
Other one :
You can use CommandName & CommandArgument and in code behind use datagridview_ItemCommand
private void dgvStandingOrder_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dgvStandingOrder.Columns[e.ColumnIndex].Name == "IsSelected" && dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
{
bool isChecked = (bool)dgvStandingOrder[e.ColumnIndex, e.RowIndex].EditedFormattedValue;
if (isChecked == false)
{
dgvStandingOrder.Rows[e.RowIndex].Cells["Status"].Value = "";
}
dgvStandingOrder.EndEdit();
}
}
private void dgvStandingOrder_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgvStandingOrder_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
{
dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}

DoubleClick on a row in ListView

Is there any possibility to get a value of doubleclicked row in ListView?
I registered an event:
private void lvLista_DoubleClick(object sender, EventArgs e)
{
MessageBox.Show(lvLista.SelectedItems.ToString());
}
But on message, when i doubleclick some row in listview i get:
System.Windows.Forms.ListView+SelectedListViewItemCollection
What is more, I have got 2 columns in listview:
lvLista.Columns.Add("ID");
lvLista.Columns.Add("Tilte");
And i want to show in messagebox the "ID" of doubleclicked row.
How to do it? How to get a values from this event?
If you handle the MouseDown and/or MouseDoubleClick events of the ListView control, and use the HitTest method to determine the target of the mouse action, you will know which item has been double clicked. This is also a good means to determine if NO item was clicked (for example, clicking on the empty area in a partially filled list.
The following code will display the clicked item in a textbox if a single click occurs, and will pop up a message box with the name of the double-clicked item if a double click occurs.
If the click or double click occur in an area of the list view not populated by an item, the text box or message box inform yopu of that fact.
This is a trivial example, and depending on your needs, you will have to mess with it a little.
UPDATE: I added some code which clears the SelectedItems property of the Listview control when an empty area of the list is clicked or double-clicked.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listView1.MouseDown += new MouseEventHandler(listView1_MouseDown);
listView1.MouseDoubleClick += new MouseEventHandler(listView1_MouseDoubleClick);
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
this.SetupListview();
}
private void SetupListview()
{
ListView lv = this.listView1;
lv.View = View.List;
lv.Items.Add("John Lennon");
lv.Items.Add("Paul McCartney");
lv.Items.Add("George Harrison");
lv.Items.Add("Richard Starkey");
}
void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);
ListViewItem item = info.Item;
if (item != null)
{
MessageBox.Show("The selected Item Name is: " + item.Text);
}
else
{
this.listView1.SelectedItems.Clear();
MessageBox.Show("No Item is selected");
}
}
void listView1_MouseDown(object sender, MouseEventArgs e)
{
ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);
ListViewItem item = info.Item;
if (item != null)
{
this.textBox1.Text = item.Text;
}
else
{
this.listView1.SelectedItems.Clear();
this.textBox1.Text = "No Item is Selected";
}
}
}
Try this:
private void lvLista_DoubleClick(object sender, EventArgs e)
{
MessageBox.Show(lvLista.SelectedItems[0].SubItems[0].Text);
}
I know this thread is old but nobody here answered the question properly in my opinion. For those in the future, try this, from MSDN:
// User must double-click to activate item
myListView.Activation = System.Windows.Forms.ItemActivation.Standard;
// Add event handler
myListView.ItemActivate += new
System.EventHandler(this.myListView_ItemClick);
Since the accepted answer didn't help me i thought that I would share my solution to the same problem: getting data from a specific column in a listview in the double click event.
The following line returns the data of the second column in the row that I've double clicked on as a string:
private void listViewOutput_DoubleClick(object sender, EventArgs e)
{
string content = listViewOutput.Items[listViewOutput.SelectedIndices[0]].SubItems[1].Text
}
Thanks; this is what I needed. I thought I'd also mention one could set up the local info variable more generally as:
ListViewHitTestInfo info = ((ListView)sender).HitTest(e.X, e.Y);
Try this
private void listView1_MouseClick(object sender, MouseEventArgs e)
{
ListViewHitTestInfo hit = listView1.HitTest(e.Location);
Rectangle rowBounds = hit.SubItem.Bounds;
Rectangle labelBounds = hit.Item.GetBounds(ItemBoundsPortion.Label);
int leftMargin = labelBounds.Left - 1;
string x = hit.Item.Text;
}

Categories

Resources