I am developing a WPF application.There is a datagrid in my Application i have created a context menu to hide and unhide column header of the datagrid while assigning the itemsource of datagrid to an IEnumerable collection.
this.dataGrid1.ItemsSource = objref.Result;
grid_data = objref.Result;
cxMenu = new ContextMenu();
foreach (Microsoft.Windows.Controls.DataGridColumn item in dataGrid1.Columns)
{
menuItem = new MenuItem();
menuItem.Header = item.Header;
menuItem.IsChecked = true;
cxMenu.Items.Add(menuItem);
menuItem.Click += new RoutedEventHandler(menuItem_Click);
menuItem.Checked += new RoutedEventHandler(menuItem_Checked);
menuItem.Unchecked += new RoutedEventHandler(menuItem_Unchecked);
}
Everythjing working fine. when i uncheck the columns are successfully remobved but when i again check the MenuItem of my ContextMenu it is not added.
Handler of my check event is as follows.
void menuItem_Checked(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
dataGrid1.ItemsSource = null;
dataGrid1.ItemsSource = objref.Result;// Again assgining the whole set to itemssource
List<string> menuList = new List<string>();
menuList.Clear();
foreach (MenuItem menuItem in cxMenu.Items)
{
if (menuItem.IsChecked == false)
{
menuList.Add(menuItem.Header.ToString());
}
}
Functionsclass objref = new Functionsclass();
foreach (string menuItem in menuList)
{
foreach (Microsoft.Windows.Controls.DataGridColumn column in dataGrid1.Columns)
{
if (column.Header.ToString() == menuItem)
{
dataGrid1.Columns.Remove(column);
break;
}
}
}
}
But my column is not added when i check again. Please help me on this.
Update 2:
void menuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
if (item.IsChecked)
{
item.IsChecked = false;
}
else
{
item.IsChecked = true;
}
}
void menuItem_Unchecked(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
foreach (Microsoft.Windows.Controls.DataGridColumn column in dataGrid1.Columns)
{
if (column.Header.ToString().Contains(item.Header.ToString()))
{
dataGrid1.Columns.Remove(column);
break;
}
}
}
Uncheck handler.
If you just want to hide/show columns, I don't think Removing/Adding columns is the right approach. I suggest you make use of the Visibility property of the column. set it to Visibility.Collapsed to hide it, then Visibility.Visible to make it visible again.
column.Visibility = Visibility.Collapsed; // Column is hidden
column.Visibility = Visibility.Visible; //Column is Visible
I have just changed my checked and Unchecked event handlers like below. Now its working fine..:)
//Unchecked handler
void menuItem_Unchecked(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
foreach (Microsoft.Windows.Controls.DataGridColumn column in dataGrid1.Columns)
{
if (column.Header.ToString().Contains(item.Header.ToString()))
{
column.Visibility = Visibility.Collapsed;
break;
}
}
}
// Checked handler
void menuItem_Checked(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
List<string> menuList = new List<string>();
menuList.Clear();
foreach (Microsoft.Windows.Controls.DataGridColumn column in dataGrid1.Columns)
{
if (column.Header.ToString().Contains(item.Header.ToString()))
{
column.Visibility = Visibility.Visible;
break;
}
}
}
Related
I have a problem with checkbox. I'm trying to explain.
My Datagrid can have multiple row, so multiple checkbox.
When one or many checkbox is true, so a button IsEnable=true. But if no checkbox is true, so the button is disable.
Maybe an issue with a count of checkbox IsChecked ? Or maybe the click processus is not appropriate?
Here is my code :
private void Chk_UID_IsSelected_Click(object sender, RoutedEventArgs e)
{
var Chkbox = sender as CheckBox;
if (Chkbox.IsChecked == true)
{
UID_Disconnect.IsEnabled = true;
}
else
{
UID_Disconnect.IsEnabled = false;
}
}
But my code check only one checkbox in fact. If i click on 2 checkbox and uncheck one, my button have an incorrect state.
My design :
Another try with no result:
private void Chk_UID_IsSelected_Click(object sender, RoutedEventArgs e)
{
foreach (CheckBox c in dgConnected_Users.ItemsSource)
{
var Chkbox = sender as CheckBox;
UID_Disconnect.IsEnabled = Chkbox.IsChecked == true;
}
}
Here another try with no result:
private void Chk_UID_IsSelected_Click(object sender, RoutedEventArgs e)
{
int checkedBoxes = dgConnected_Users.Items
.OfType<CheckBox>().Count(c => (bool)c.IsChecked == true);
if (checkedBoxes > 0)
{
// You shall pass!
UID_Disconnect.IsEnabled = true;
}
else
{
// None shall pass
UID_Disconnect.IsEnabled = false;
}
}
OK I have progress in my code, here the new one :
private void Chk_UID_IsSelected_Click(object sender, RoutedEventArgs e)
{
foreach (DataRowView dr in dgConnected_Users.ItemsSource)
{
var Chkbox = sender as CheckBox;
if (Chkbox.IsChecked == true)
{
isAnyChecked++;
}
else
{
isAnyChecked--;
}
}
if (isAnyChecked > 0)
{
UID_Disconnect.IsEnabled = true;
}
else
{
UID_Disconnect.IsEnabled = false;
}
}
That do the staff, but i know that if I check just one checkbox, 'isAnyChecked' = 2, or it must be equal 1.
I have a datagridview binded to a BindingList and inside this list I have comboboxes binded to a list which is a property of my BindingList, for understanding better:
ListA ---> binded to datagridview
ListA.ListB ---> binded to comboboxes
When I open the form I can corectly set my comboboxes showing the values inside the ListB, but when I add a new item I get an error (value is not valid), here is the code:
private void dataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
((DataGridViewComboBoxColumn)dataGridView.Columns["Names"]).DisplayIndex = 4;
for (int i = 0; i < People.Count; i++)
{
var cell = (DataGridViewComboBoxCell)dataGridView.Rows[i].Cells["Names"];
cell.DataSource = People[i].Names;
cell.Value = People[i].Names[0];
}
}
The code above works great, the problem happens here:
private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (dataGridView.CurrentCell.ColumnIndex != dataGridView.Columns["Names"].Index)
return;
var cell = (DataGridViewComboBoxCell)dataGridViewICAO.CurrentCell;
if (cell.EditedFormattedValue.ToString().Equals(String.Empty)) return;
var regex = new Regex("[a-zA-Z]");
if (!regex.IsMatch(cell.EditedFormattedValue.ToString()))
e.Cancel = true;
else
{
People[cell.RowIndex].Names.Add(cell.EditedFormattedValue.ToString());
cell.Value = People[cell.RowIndex].Names.Last();
People[cell.RowIndex].Names = cell.Value.ToString();
}
}
on the row code cell.Value = People[cell.RowIndex].Names.Last(); I get the exception... Thanks to all!
This is how I set the combobox:
private void AddComboBox()
{
var comboNames = new DataGridViewComboBoxColumn { Name = "cmbNames", HeaderText = "Names" };
dataGridView.Columns.Add(comboNames);
}
private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView.CurrentCell.ColumnIndex == dataGridView.Columns["cmbNames"].Index)
{
var combo = e.Control as ComboBox;
if (combo == null)
return;
combo.DropDownStyle = ComboBoxStyle.DropDown;
}
}
I have a datagridview which contain a Combobox Column i want when i select a add value from the combobox it shows a new form. i tried this code but it doesn't work:
private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
switch (dataGridView2.Columns[e.ColumnIndex].Name)
{
case "CategorieDataGridViewTextBoxColumn":
if (dataGridView2.Rows[e.RowIndex].Cells["CategorieDataGridViewTextBoxColumn"].Value.ToString() == "Add")
{
Categorie cat = new Categorie();
cat.Show();
}
break;
}
}
So how can i do it??
You should handle the event when a value is changed in a ComboBox in a DataGridView cell. try this code which will fire the event of the selection in the comboBox in the dataGridView:
public Form1()
{
InitializeComponent();
DataGridViewComboBoxColumn cmbcolumn = new DataGridViewComboBoxColumn();
dataGridView2.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView2_EditingControlShowing);
}
private void dataGridView2_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox combo = e.Control as ComboBox;
if (combo != null)
{
combo.SelectedIndexChanged -= new EventHandler(ComboBox_SelectedIndexChanged);
combo.SelectedIndexChanged += new EventHandler(ComboBox_SelectedIndexChanged);
}
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cb = (ComboBox)sender;
string item = cb.Text;
if (item == "Add")
{
Categorie cat = new Categorie();
cat.Show();
}
}
I found a way to add a combobox to DataGridview (Winform) cell, but I have not found an event like ItemDataBound of DataGridView to set a value to comboBox. And do not know how to set a selected value of a comboBox to DataItem property of a current row (of a DataGridView) :(
Please give me some clues to do this task
Thanks you so much
You can use below method to add data to a combobox in gridview. If you dont have a list you can add items to the combobox as:
cmbdgv.Items.Add("Test");
private void bindDataToDataGridViewCombo() {
DataGridViewComboBoxColumn cmbdgv = new DataGridViewComboBoxColumn();
List<String> itemCodeList = new List<String>();
cmbdgv.DataSource = itemCodeList;
cmbdgv.HeaderText = "Test";
cmbdgv.Name = "Test";
cmbdgv.Width = 270;
cmbdgv.Columns.Add(dgvCmbForums);
cmbdgv.Columns["Test"].DisplayIndex = 0;
}
After adding if you want to capture the combobox selection change you can use below event in the datagridview.
ComboBox cbm;
DataGridViewCell currentCell;
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
cbm = (ComboBox)e.Control;
if (cbm != null)
{
cbm.SelectedIndexChanged += new EventHandler(cbm_SelectedIndexChanged);
}
currentCell = this.dataGridView1.CurrentCell;
}
}
void cbm_SelectedIndexChanged(object sender, EventArgs e)
{
this.BeginInvoke(new MethodInvoker(EndEdit));
}
void EndEdit()
{
if (cbm != null)
{
string SelectedItem=cbm.SelectedItem.ToString();
int i = dataGridView1.CurrentRow.Index;
dataGridView1.Rows[i].Cells["Test"].Value = SelectedItem;
}
}
If you are trying to set the value to a Combobox in a DataGridView, see if this answer will help.
To get the selected item of the Combobox (example):
comboBox.SelectedIndexChanged += new EventHandler(comboBox_ComboSelectionChanged);
private void comboBox_ComboSelectionChanged(object sender, EventArgs e)
{
if (myDGV.CurrentCell.ColumnIndex == 5)
{
int selectedIndex;
string selectedItem;
selectedIndex = ((ComboBox)sender).SelectedIndex; // handle an error here.
// get the selected item from the combobox
var combo = sender as ComboBox;
if (selectedIndex == -1)
{
MessageBox.Show("No value has been selected");
}
else
{
// note that SelectedItem may be null
selectedItem = combo.SelectedItem.ToString();
if (selectedItem != null)
{
// Your code
I have menu ServerList, I am adding the menuItems dynamically using C# code. It reads the servers list from file and populate the menu items. I have added the right click options for each server. Edit & Delete.
All this is working fine. the problem is how do I read actual server name when Edit/Detele is clicked.
Here is the code
public MainWindow()
{
InitializeComponent();
LoadMenuItems();
}
//Currently static values, but reads from file. later
private void LoadMenuItems()
{
MenuItem item2 = new MenuItem();
item2.Header = "Server1";
AddContextMenu(item2);
MenuItem item3 = new MenuItem();
item3.Header = "Server2";
AddContextMenu(item3);
ActualMenu.Items.Add(item2);
ActualMenu.Items.Add(item3);
}
private void AddContextMenu(MenuItem item)
{
MenuItem item1 = new MenuItem();
item1.Header = "Edit";
item1.Click += item_Click;
MenuItem item2 = new MenuItem();
item2.Header = "Detlete";
item2.Click += item_Click;
ContextMenu menu = new ContextMenu();
menu.Items.Add(item1);
menu.Items.Add(item2);
item.ContextMenu = menu;
}
void item_Click(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
string header = item.Header.ToString();
}
For this use PlacementTarget.
private void AddContextMenu(MenuItem item)
{
MenuItem item1 = new MenuItem();
....
ContextMenu menu = new ContextMenu();
....
menu.PlacementTarget = item; /// 'Connects' context menu to source menu item.
item.ContextMenu = menu;
}
void item_Click(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
string header
= ((MenuItem)((ContextMenu)((MenuItem)sender).Parent).PlacementTarget).Header;
}
Cheers.
By default, the Header of a MenuItem uses a TextBlock to display content. So, in this case you need to convert the Header to a TextBox, then look at the Text property.
For example,
void item_Click(object sender, RoutedEventArgs e){
string servername = ((sender as MenuItem).Header as TextBlock).Text;
}