How to access the object a selected row is representing? - c#

I have a SortablebindingList<Record> as a DataSource for my DataGridView. I also have dataGridView.CellContentDoubleClick mapped to my selectionDblClicked() fuction.
dataGridView.CellContentDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(selectionDblClicked);
...
void selectionDblClicked(object sender, EventArgs e)
{
//Do something with the underlying `record` object...
}
Now, EventHandlers pass a sender object and an EventArgs argument.
My question is how does one use the DataGridViewCellEventHandler to access the underlying object that was "double clicked"?

Use the DataBoundItem property of the clicked row.
To see which row was clicked, use RowIndex property of DataGridViewCellEventArgs.
void selectionDblClicked(object sender, DataGridViewCellEventArgs e)
{
var rowClicked = dataGridView.Rows[e.RowIndex];
DoSomething(rowClicked.DataBoundItem as Record);
}

Related

How to add and remove values from ComboBox to CheckedListBox

What I need:
I need a ComboBox and a CheckedListBox with exact same values.
I have a Button to add values and delete values.
Here is my Add Button:
private void button5_Click(object sender, EventArgs e)
{
checkedListBox1.Items.Add(comboBox1.Text);
comboBox1.Items.Add(comboBox1.Text);
comboBox1.Text = "";
}
and my Delete Button:
private void button6_Click(object sender, EventArgs e)
{
comboBox1.Items.Remove(comboBox1.SelectedItem);
}
I would like to be able to delete the entries in the CheckedListBox without having to select it first, I only need it to be selected into the comboBox1.
Since you're adding the same strings, you can use the IndexOf() method to get the index where the current string is located in your CheckedListBox and the RemoveAt() to remove it.
Verify that the ComboBox.SelectedItem is not null. You can use the GetItemText() method to get the string currently selected. If the SelectedItem is null, you get back a empty string.
private void button6_Click(object sender, EventArgs e)
{
string currentItem = comboBox1.GetItemText(comboBox1.SelectedItem);
if (!string.IsNullOrEmpty(currentItem))
{
checkedListBox1.Items.RemoveAt(checkedListBox1.Items.IndexOf(currentItem));
comboBox1.Items.Remove(comboBox1.SelectedItem);
}
}
Method2:
If the Items it the two controls are located at the same index, you can instead use the ComboBox.SelectedIndex to RemoveAt() both:
private void button6_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex >= 0)
{
checkedListBox1.Items.RemoveAt(comboBox1.SelectedIndex);
comboBox1.Items.RemoveAt(comboBox1.SelectedIndex);
}
}

How to catch if cell Value got changed in DataGridView as sender

I haven't found something that matches my problem so I ask it here. I have some code which belongs to a Textbox:
if ((sender as TextBox).Text == form1.filterType())
{
//Do something
}
This comes from the TextBox TextChanged event. So when the TextChanged Event gets fired it calls a method which has the if-construct above and recognizes that the textchanged event came from the textbox.
Now I want exactly the same just when someone writes into a cell in a DataGridView (not when it's just clicked - when the content changes).
How to do this correctly and which event fires when the content changes in a cell without leaving the cell?
I have found a solution for this:
private void Form1_Load(object sender, EventArgs e)
{
this.dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
}
void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
TextBox tb = (TextBox)e.Control;
//"unwire" the event before hooking it up ensures the event handler gets called only once
tb.TextChanged -= new EventHandler(tb_TextChanged);
tb.TextChanged += new EventHandler(tb_TextChanged);
}
}
void tb_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("changed");
}
Now it fires everytime the value in the cell gets changed - it behaves like a textbox.
Now - I still need a solution for the "if-construct" above. How to do this exactly? I've casted the cell into a textbox but now? Does this still comes from the dataGridview?
Once I had a similar problem an solved it this way (think there are better ones but it worked)
private void DataGridView1_onFocus ( Object sender, EventArgs e)
{
DataGridView1.onKeyPress+=DataGridView1_onKeyStroke;
}
private void DataGridView1_onFocusLost( Object sender, EventArgs e)
{
DataGridView1.onKeyPress-=DataGridView1_onKeyStroke;
}
private void DataGridView1_onKeyStroke( Object sender , EventArgs e)
{
//Do your thing
}

select row from winforms listview

I have listview which is populated with list of data. Now I want to select desired row and on click button to recognize that item to delete from a collection.
Question is how to recognize selected row from the listview?
private void buttonDelete_Click(object sender, EventArgs e)
{
//selected data is of custom type MyData
var selected = (MyData)....?
}
Thanks
This should works
private void buttonDelete_Click(object sender, EventArgs e)
{
//selected data is of custom type MyData
var selected = yourListView.SelectedItems.First();
}
To add to #Zaphod's answer and make a little more robust:
private void buttonDelete_Click(object sender, EventArgs e)
{
if (yourListView.SelectedItems.Any())
{
//selected data is of custom type MyData
var selected = yourListView.SelectedItems.First();
}
}
You could use .Count > 0 instead of .Any() and .SelectedItems[0] instead of .First(). Whatever you find more readable/maintainable.
Old School answer :) without any LINQ statements
if(yourListView.SelectedItems.Count > 0)
{
var item = yourListView.SelectedItems[0];
}
I don't think you have to use casting for a deleting operation, just remove all the selected indices like this:
private void buttonDelete_Click(object sender, EventArgs e){
for (int i = listView1.SelectedIndices.Count - 1; i >= 0; i--)
listView1.Items.RemoveAt(listView1.SelectedIndices[i]);
}
or more simply:
private void buttonDelete_Click(object sender, EventArgs e){
foreach(ListViewItem item in listView1.SelectedItems)
listView1.Items.Remove(item);
}
As you can see the item which is selected is of type ListViewItem, you can bind your data to this item via Text property (if the data is string) or Tag property. I don't understand what your CustomData is, is it a type inheriting ListViewItem?
YOu should do this
private void buttonDelete_Click(object sender, EventArgs e)
{
if (yourListView.SelectedItems.Any())
{
//selected data is of custom type MyData
var selected = (MyData)yourListView.SelectedItems[0];
YourCollection.Remove(selected);
}
}

Getting data from selected datagridview row and which event?

I have a DataGridView (Selectionmode: FullRowSelect) on a windows form along with some textboxes, so what i want to do is that whenever a user selects a row(click or double_click maybe), the contents of that row must be displayed in the text boxes,
I tried out this code:
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("CEll Double_Click event calls");
int rowIndex = e.RowIndex;
DataGridViewRow row = dataGridView1.Rows[rowIndex];
textBox5.Text = row.Cells[1].Value;
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
DataGridViewRow row = dataGridView1.Rows[rowIndex];
textBox5.Text = dataGridView1.Rows[1].Cells[1].Value.ToString();// row.Cells[1].Value;
}
there are many other textboxes, but the main problem is that none of the event seems to be triggered, what event should i use to do so, or is there some property of datagrid that i might have set wrong?
Any help would be appreciated...:(
You can use SelectionChanged event since you are using FullRowSelect selection mode. Than inside the handler you can access SelectedRows property and get data from it. Example:
private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView.SelectedRows)
{
string value1 = row.Cells[0].Value.ToString();
string value2 = row.Cells[1].Value.ToString();
//...
}
}
You can also walk through the column collection instead of typing indexes...
You can try this click event
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0)
{
DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex];
Eid_txt.Text = row.Cells["Employee ID"].Value.ToString();
Name_txt.Text = row.Cells["First Name"].Value.ToString();
Surname_txt.Text = row.Cells["Last Name"].Value.ToString();
First take a label.
set its visibility to false, then on the DataGridView_CellClick event write this
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
label.Text=dataGridView1.Rows[e.RowIndex].Cells["Your Coloumn name"].Value.ToString();
// then perform your select statement according to that label.
}
//try it it might work for you
You should check your designer file. Open Form1.Designer.cs and
find this line:
windows Form Designer Generated Code.
Expand this and you will see a lot of code. So check Whether this line is there inside datagridview1 controls if not place it.
this.dataGridView1.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellClick);
I hope it helps.
Simple solution would be as below. This is improvement of solution from vale.
private void dgMapTable_SelectionChanged(object sender, EventArgs e)
{
int active_map=0;
if(dgMapTable.SelectedRows.Count>0)
active_map = dgMapTable.SelectedRows[0].Index;
// User code if required Process_ROW(active_map);
}
Note for other reader, for above code to work FullRowSelect selection mode for datagridview should be used. You may extend this to give message if more than two rows selected.
You can use the SelectionChanged Event.
CurrentRow.DataBoundItem will give the bound item.
SelectionMode property should be full row select.
var item = ([CastToBindedItem])dataGridLocations.CurrentRow.DataBoundItem;
tbxEditLocation.Text = item.Name;

Problem displaying data in gridview with object data source (L2S)

I have a gridview using object datasource for data binding. Everything is working fine except, When i add some new records to data it is not displaying immediately, it requires a refresh. I am using L2S Business Object with Object Data Source. Same thing in update and delete events.
I think you miss EditIndex property, change it on every event, like :
protected void HlnkbInsert_Click(object sender, EventArgs e)
{
...
gv.EditIndex = -1;
DataBindGV();
}
protected void gv_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
...
gv.EditIndex = -1;
DataBindGV();
}
protected void gv_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
...
gv.EditIndex = -1;
DataBindGV();
}
protected void gv_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
...
gv.EditIndex = e.NewSelectedIndex;
DataBindGV();
}
Are you re-binding your GridView after making the changes to your data?

Categories