I have a DataGridView bound to a DataTable. I added a DataGridViewButtonColumn that serves as the delete button for the row.
Since it is bound to a DataTable, I'd like to be able to get the object of the row with the delete button clicked so I can delete it from the DataTable and then refresh the DataGrid.
This is how my button is setup:
var colDelete = new DataGridViewButtonColumn();
colDelete.Name = "DeleteButton";
colDelete.HeaderText = "Delete";
colDelete.Text = "Delete";
colDelete.UseColumnTextForButtonValue = true;
colDelete.DataPropertyName = "EthnicityDetailID";
colDelete.DisplayIndex = 10;
dataGridEthnicityData.Columns.Add(colDelete);
This is how I'm planning to handle the button click event:
private void dataGridEthnicityData_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
try
{
var senderGrid = (DataGridView)sender;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.ColumnIndex == senderGrid.Columns["DeleteButton"].Index)
{
//ethnicityDataTable.Rows.RemoveAt(e.RowIndex);
dataGridEthnicityData.Refresh();
}
}
catch (Exception ex)
{
MessageBox.Show("Error deleting ethnicity data: " + ex.Message + " " + ex.StackTrace);
}
}
How do I assign EthnicityDetailID as the value for the button and how do I retrieve the row with the button clicked as an object so I can retrieve the value and delete accordingly in the datatable?
Thank you.
Apparently you have bound your DataTable to the DataSource of your DataGridView. If you have separated your Data from how the data is displayed, you will have code that is similar to:
BindingList<Ethnicity> DisplayedEthnicities
{
get => (BindingList<Ethnicity>) this.dataGridView1.DataSource,
set => this.dataGridView1.DataSource = value;
}
Ethnicity GetEthnicity(DataGridViewRow row)
{
return (Ethnicity)row.DataboundItem;
}
Ethnicity CurrentEthnicity => this.dataGridView1.CurrentCell?.OwnindRow as Ethnicity;
IEnumerable<Ethnicity> SelectedEthnicities => this.dataGridView1.SelectedRows
.Select(row => this.GetEthnicity(row));
You also need conversions between Datatable and Ethnicity:
void IEnumerable<Ethnicities> ToEthnicities(DataTable dataTable)
{
// TODO: convert the rows of the datatable into Ethnicities
}
You know better than I do how the ethnicities are in your datatable.
After this, filling the DataGridView will be easy:
DataTable CreateDataTable()
{
// TODO: fill the datatable with data from database? CSV file? Json?
}
void FillDataGridView()
{
var dataTable = this.CreateDataTable();
var ethnicities = this.ToEthnicities(dataTable);
this.DisplayedEthnicities = new BindingList<Enthnicity>(ethnicities.ToList());
}
I'd like to be able to get the object of the row with the delete button clicked
After you've done it like this, getting the databound item will be easy:
void OnCellContent_Clicked(object sender, DataGridViewCellEventArgs e)
{
DataGridViewRow row = this.DataGridView1.Rows[e.RowIndex];
Ethnicity ethnicity = this.GetEthnicity(row);
ProcessEthnicity(ethnicity);
}
I am developing a Windows Forms Application using Visual Studio in Visual C++. My form has 96 check boxes on it. Rather than create 96 Click events, I believe that there's a way to create a single Click event that is called when any check box is clicked. Within the Click event, I need to determine whether the active checkbox is Checked or Not Checked. While this should be easy, I can't seem to figure it out!
I got it to work with the code below, but I'm sure there's a better way.
if (sender == checkBox_D1)
{
if (checkBox_D1->Checked)
isChecked = true;
}
else if (sender == checkBox_D2)
{
if (checkBox_D2->Checked)
isChecked = true;
}
else
return; // Invalid sender - should not get here!
if (isChecked)
{
// Do something
}
else
{
// Do something else
}
I also tried the code below but activeCheckBox is not a Checkbox object so it doesn't work.
Control^ activeCheckBox = ActiveControl;
activeCheckBox->Text returns the Text property of the Checkbox
activeCheckBox->Checked doesn't compile. The error is 'Checked' : is not a member of 'System::Windows::Forms::Control'
It seems like sender has the data that I need but I don't know how to access it.
Is there a way to declare a Checkbox as follows?
CheckBox activeBox;
and then assign activeBox to the Checkbox that has the focus
activeBox = ???
// Then just need to do this!
if (activeBox.Checked)
isChecked = true;
Thank you for the help.
Yes you can reuse the same function for all your Check boxes.
void App3::ItemPage::checkBox_Checked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
CheckBox^ activeCheckBox = safe_cast<CheckBox^>(sender);
if (activeCheckBox->Checked)
{
if (activeCheckBox->Name == "checkBox_D1") {
//Do something when this check box is clicked.
}
if (activeCheckBox->Name == "checkBox_D2") {
//Do something when this check box is clicked.
}
}
}
For all checBoxes you will assign the same CheckedChanged event:
checkBox1.CheckedChanged += newCheckBoxCheckedOrUnchecked_CheckedChanged;
checkBox2.CheckedChanged += newCheckBoxCheckedOrUnchecked_CheckedChanged;
//...
//...
checkBox95.CheckedChanged += newCheckBoxCheckedOrUnchecked_CheckedChanged;
checkBox96.CheckedChanged += newCheckBoxCheckedOrUnchecked_CheckedChanged;
Checks the state of all checkBoxes:
private void newCheckBoxCheckedOrUnchecked_CheckedChanged(object sender, EventArgs e)
{
foreach (Control control in this.Controls)
{
if (control.GetType() == typeof(CheckBox))
{
var checkBox = (CheckBox) control;
var checkBoxName = checkBox.Name; // To know which checkbox we are talking about
var checkBoxIsChecked = checkBox.Checked;
// Do your stuff
MessageBox.Show(checkBoxName + #" is " + (checkBoxIsChecked ? "checked" : "not checked"));
}
}
}
Checks the state of only the checkBox where the value was changed:
private void newCheckBoxCheckedOrUnchecked_CheckedChanged(object sender, EventArgs e)
{
var checkBox2 = (CheckBox)sender;
var checkBoxName2 = checkBox2.Name; // To know which checkbox we are talking about
var checkBoxIsChecked2 = checkBox2.Checked;
// Do your stuff
MessageBox.Show(checkBoxName2 + #" is " + (checkBoxIsChecked2 ? "checked" : "not checked"));
}
I have a ToolStrip with a ToolStripDropDownButton to which I am adding ToolStripMenuItems in run time in my code. I need to have a default ContextMenuStrip and assign it to each menu item so when the user right clicks a menu item he will get that context menu strip.
Is it possible ?
I appreciate your help.
I found a good solution at: enter link description here
To save you the reading I also add the solutuin here:
void MenuItemContext(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) return;
ToolStripMenuItem mID = (ToolStripMenuItem)sender;
ContextMenu tsmiContext = new ContextMenu();
MenuItem Item1 = new MenuItem();
MenuItem Item2 = new MenuItem();
Item1.Text = "Item1";
Item2.Text = "Item2";
tsmiContext.MenuItems.Add(Item1);
tsmiContext.MenuItems.Add(Item2);
Item1.Click += new EventHandler(Item1_Click);
Item2.Click += new EventHandler(Item2_Click);
hndPass = mID.Text;
tsmiContext.Show(menuStrip1, menuStrip1.PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y)));
}
private String hndPass;
void Item1_Click(object sender, EventArgs e)
{
MenuItem mID = (MenuItem)sender;
MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass);
}
void Item2_Click(object sender, EventArgs e)
{
MenuItem mID = (MenuItem)sender;
MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass); ;
}
Have fun (-:
Seems like I worked out something useful,this is obviously not perfect but should give you a decent starting point.I assume you've a ContextMenuStrip named contextmenustrip1,some drop down items of which one is aaaToolStripMenuItem.Then create a private boolean field,
private static bool clickReleased=false;
In the MouseDown event of aaaTool... write the following code;
if (e.Button == MouseButtons.Right)
clickReleased = true;
then in MouseUp event,write this;
if (e.Button == MouseButtons.Right)
{
if (clickReleased)
{
contextMenuStrip1.Show(Cursor.Position);
clickReleased = false;
}
}
Hope this helps.
I have my grid panel as follows
<ext:GridPanel ID="GridPanel1" runat="server" Height="300" Title="Title">
<ColumnModel runat="server">
<Columns>
</Columns>
</ColumnModel>
<Store>
<ext:Store ID="Store1" runat="server" EnableViewState="true">
</ext:Store>
</Store>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" SingleSelect="true" runat="server">
</ext:RowSelectionModel>
</SelectionModel>
<Buttons>
<ext:Button ID="btnDelete" runat="server" Text="Delete">
<DirectEvents>
<Click OnEvent="Delete">
<ExtraParams>
<ext:Parameter Name="Values" Value="Ext.encode(#{GridPanel1}.getRowsValues({selectedOnly:true}))"
Mode="Raw" />
</ExtraParams>
</Click>
</DirectEvents>
</ext:Button>
</Buttons>
</ext:GridPanel>
This is my grid from my database
This is my code to delete the selected row but this is looping for row value as i used dictionary
protected void Delete(object sender, DirectEventArgs e)
{
string json = e.ExtraParams["Values"];
string value = string.Empty;
Dictionary<string, string>[] companies = JSON.Deserialize<Dictionary<string, string>[]>(json);
bool addHeader = true;
foreach (Dictionary<string, string> row in companies)
{
if (addHeader)
{
//sb.Append("<tr>");
foreach (KeyValuePair<string, string> keyValuePair in row)
{
value = keyValuePair.Value.ToString();
SqlConnection con = new SqlConnection(connection);
con.Open();
SqlCommand cmd = new SqlCommand("Delete from Users where Name='" + value + "'", con);
cmd.ExecuteNonQuery();
BindData();
}
addHeader = false;
}
}
}
If I select first row and click on delete I would like to delete that row and Bind grid again. Can any one tell how to do this. Also I would like to alert a message box if the user didn't select any row using Java script
Is this ExtJs4? Look for getSelectionModel().getSelection() method of your grid control.
I have a DataGrid, bound to Database table, I need to get the content of selected row in DataGrid, for example, I want to show in MessageBox content of selected row.
Example of DataGrid:
So, if I select the second row, my MessageBox has to show something like: 646 Jim Biology.
You can use the SelectedItem property to get the currently selected object, which you can then cast into the correct type. For instance, if your DataGrid is bound to a collection of Customer objects you could do this:
Customer customer = (Customer)myDataGrid.SelectedItem;
Alternatively you can bind SelectedItem to your source class or ViewModel.
<Grid DataContext="MyViewModel">
<DataGrid ItemsSource="{Binding Path=Customers}"
SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"/>
</Grid>
If you're using the MVVM pattern you can bind a SelectedRecord property of your VM with SelectedItem of the DataGrid, this way you always have the SelectedValue in you VM.
Otherwise you should use the SelectedIndex property of the DataGrid.
public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (null != row) yield return row;
}
}
private void DataGrid_Details_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var row_list = GetDataGridRows(DataGrid_Details);
foreach (DataGridRow single_row in row_lis)
{
if (single_row.IsSelected == true)
{
MessageBox.Show("the row no."+single_row .GetIndex ().ToString ()+ " is selected!");
}
}
}
catch { }
}
This is pretty simple in this DataGrid dg and item class is populated in datagrid and listblock1 is a basic frame.
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var row_list = (Item)dg.SelectedItem;
listblock1.Content = "You Selected: " + row_list.FirstName + " " + row_list.LastName;
}
catch { }
}
public class Item
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
You can also:
DataRowView row = dataGrid.SelectedItem as DataRowView;
MessageBox.Show(row.Row.ItemArray[1].ToString());
Well I will put similar solution that is working fine for me.
private void DataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
if (DataGrid1.SelectedItem != null)
{
if (DataGrid1.SelectedItem is YouCustomClass)
{
var row = (YouCustomClass)DataGrid1.SelectedItem;
if (row != null)
{
// Do something...
// ButtonSaveData.IsEnabled = true;
// LabelName.Content = row.Name;
}
}
}
}
catch (Exception)
{
}
}
#Krytox answer with MVVM
<DataGrid
Grid.Column="1"
Grid.Row="1"
Margin="10" Grid.RowSpan="2"
ItemsSource="{Binding Data_Table}"
SelectedItem="{Binding Select_Request, Mode=TwoWay}" SelectionChanged="DataGrid_SelectionChanged"/>//The binding
#region View Model
private DataRowView select_request;
public DataRowView Select_Request
{
get { return select_request; }
set
{
select_request = value;
OnPropertyChanged("Select_Request"); //INotifyPropertyChange
OnSelect_RequestChange();//do stuff
}
}
private void Fetching_Record_Grid_MouseDoubleClick_1(object sender, MouseButtonEventArgs e)
{
IInputElement element = e.MouseDevice.DirectlyOver;
if (element != null && element is FrameworkElement)
{
if (((FrameworkElement)element).Parent is DataGridCell)
{
var grid = sender as DataGrid;
if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
{
//var rowView = grid.SelectedItem as DataRowView;
try
{
Station station = (Station)grid.SelectedItem;
id_txt.Text = station.StationID.Trim() ;
description_txt.Text = station.Description.Trim();
}
catch
{
}
}
}
}
}
Just discovered this one after i tried Fara's answer but it didn't work on my project. Just drag the column from the Data Sources window, and drop to the Label or TextBox.
use your Model class to get row values selected from datagrid like,
XDocument xmlDoc = XDocument.Load(filepath);
if (tablet_DG.SelectedValue == null)
{
MessageBox.Show("select any record from list..!", "select atleast one record", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
}
else
{
try
{
string tabletID = "";
/*here i have used my model class named as TabletMode*/
var row_list = (TabletModel)tablet_DG.SelectedItem;
tabletID= row_list.TabletID;
var items = from item in xmlDoc.Descendants("Tablet")
where item.Element("TabletID").Value == tabletID
select item;
foreach (var item in items)
{
item.SetElementValue("Instance",row_list.Instance);
item.SetElementValue("Database",row_list.Database);
}
xmlDoc.Save(filepath);
MessageBox.Show("Details Updated..!"
+ Environment.NewLine + "TabletId: " +row_list.TabletID + Environment.NewLine
+ "Instance:" + row_list.Instance + Environment.NewLine + "Database:" + row_list.Database, "", MessageBoxButton.YesNoCancel, MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace);
}
}
if I select the second row -
Dim jason As DataRowView
jason = dg1.SelectedItem
noteText.Text = jason.Item(0).ToString()
noteText will be 646. This is VB, but you get it.
There are a lot of answers here that probably work in a specific context, but I was simply trying to get the text value of the first cell in a selected row. While the accepted answer here was the closest for me, it still required creating a type and casting the row into that type. I was looking for a simpler solution, and this is what I came up with:
MessageBox.Show(((DataRowView)DataGrid.SelectedItem).Row[0].ToString());
This gives me the first column in the selected row. Hopefully this helps someone else.
I got something like this:
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) {
DataGrid dg = (DataGrid)sender;
DataRowView selectedRow = dg.SelectedItem as DataRowView;
if(selectedRow != null) {
txtXXX.Text = selectedRow["xxx"].ToString();
txtYYY.Text = selectedRow["yyy"].ToString();
txtZZZ.Text = selectedRow["zzz"].ToString();
}
}
Your front code:
set your model namespace xmlns:viewModel="clr-namespace:CPL3_workstation.MVVM.ModelViews.Tables"
set xmlns:d="http://schemas.microsoft.com/expression/blend/2008", because d:DataContext="{d:DesignInstance...}
<DataGrid d:DataContext = "{d:DesignInstance viewModel:TestViewModel, IsDesignTimeCreatable = True}"
ItemsSource = "{Binding Rows}"
SelectedItem = "{Binding Selector}">
<DataGrid.Columns>
<DataGridTextColumn
Binding = "{Binding Content1}"
Header = "Column 1" />
<DataGridTextColumn
Binding = "{Binding Content2}"
Header = "Column 2" />
<DataGridTextColumn
Binding = "{Binding Content3}"
Header = "Column 3" />
</DataGrid.Columns>
</DataGrid>
Your ViewModel and the Model below:
namespace CPL3_workstation.MVVM.ModelViews.Tables
{
public class TestViewModel
{
public IEnumerable<TestModel> Rows { get; set; }
public TestModel Selector
{
get => selector;
set => selector = value;
}
private TestModel selector;
public TestViewModel()
{
Rows = new List<TestModel>
{
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" }
};
}
}
public class TestModel
{
public string Content1 { get; set; }
public string Content2 { get; set; }
public string Content3 { get; set; }
}
}
As you can see, the SelectedItem has a binding to the Selector property of the type of your model.