I have a strange problem with DataGrid context menu. I load item details from server after click on a item in datagrid. While loading the details the application shows a waitscreen:
private void gridViewOrders_MouseDown (object sender, MouseEventArgs e)
{
GridView gv = sender as GridView;
if (gv != null)
{
ShowWaitScreen (message);
GridHitInfo ghi = gv.CalcHitInfo (e.Location);
...
CloseWaitScreen ( );
}
}
When the user click the right mouse button, it should shows a context menu:
private void gridViewOrders_PopupMenuShowing (object sender, PopupMenuShowingEventArgs e)
{
if (e.MenuType == GridMenuType.Row)
{
DXMenuItem item = new DXMenuItem ("Delete", OnBtnDeleteOrder_Click);
e.Menu.Items.Add (item);
}
}
But the menu disappear at once. When I remove the waitscreen, the context menu is shown and the user can select the "Delete" menuitem. Any hints, how I can fix this problem? Thank you!
A good solution for my problem is to do the following:
private void gridViewOrders_MouseDown (object sender, MouseEventArgs e)
{
GridView gv = sender as GridView;
if (gv != null)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
ShowWaitScreen (message);
...
CloseWaitScreen ( )
}
}
}
Thanks to the DevExpress team for the hint!
I dont really thisnk you need to handle anything in MouseDown event.
This code works for GridView:
private void gridView1_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
{
GridView view = sender as GridView;
if (e.MenuType == DevExpress.XtraGrid.Views.Grid.GridMenuType.Row)
{
int rowHandle = e.HitInfo.RowHandle;
e.Menu.Items.Clear();
DXMenuItem zaznaczItem = new DXMenuItem("Zaznacz wszystkie", new EventHandler(zaznacz_Click));
DXMenuItem odznaczItem = new DXMenuItem("Odznacz wszystkie", new EventHandler(odznacz_Click));
e.Menu.Items.Add(zaznaczItem);
e.Menu.Items.Add(odznaczItem);
}
}
void zaznacz_Click(object sender, EventArgs e)
{
foreach (DataRow dr in (gcKontrahent.DataSource as DataTable).Rows)
{
dr["checkbox"] = true;
}
}
Handler zaznacz_Click is just example of handler for selected menu item. odznacz_Click is similar so I didnt post it. I dont have example for DataGrid so excuise me if it's not good solution. Just take it as example for acomplishing context menu handling in GridView.
Related
I´m building a ContextMenu on the fly, like this
readinstance = null;
ContextMenu cMenu = new ContextMenu();
for (int i = 0; i < instances.Length; i++) {
string text = String.Format("{0} - {1}", instances[i].Id, instances[i].FormName);
MenuItem item = new MenuItem(text, new EventHandler(cMenuitem_Click));
item.Tag = instances[i];
cMenu.MenuItems.Add(item);
}
cMenu.Show((Button)sender, new Point(0, 0));
cMenu.Dispose();
if (readinstance == null)
throw new Exception("Must select some instance");
and the handler is
void cMenuitem_Click(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
readinstance = (FormPrintingStorage)item.Tag;
}
The menu displays correctly, but when I click some of the options, the handler is not called, so readinstance remains null, and the exception throws. As a side note, when I click any of the options, the menu disappears.
I cannot see what is wrong with my code. Any help will be appreciated.
I´m answering my own question, because I tried more ways.
The first one was to replace the ContextMenu with a ListView and an "Ok" button, at no luck, because the wait loop needed a Thread.Sleep. No comments.
The solution was to implement a new dialog with an empty list view an the Ok button. Some of the relevant code follows. Note that only TreeViewItem/s are moved between the main form and the dialog.
ListViewItem _result = null;
public ListViewItem Result { get { return _result; } }
public List<ListViewItem> Source
{
set
{
listView1.Items.Clear();
foreach (ListViewItem item in value)
listView1.Items.Add(item);
listView1.View = View.List;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (_result == null)
return;
DialogResult = DialogResult.OK;
Close();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
ListView list = (ListView)sender;
ListView.SelectedIndexCollection indices = list.SelectedIndices;
if (indices.Count == 0)
return;
_result = list.Items[indices[0]];
}
Getting the Result, the main form may do anything it wants with the Tag member. In fact, I´m using the same dialog for two different purposes in the same form.
I have a DataGrid with a ComboBox column and I need to add items to that combobox only when it get focus. I handle the event GotFocus, but still have a problem. In fact once I select an item from the dropdown the event will fire again. Any workaround on how to fix this issue.
private void CmbxGotFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource.GetType() != typeof(ComboBoxItem) && !this.returnedFocus)
{
//dowork
}
}
private void CmbxLostFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource.GetType() != typeof(ComboBoxItem))
{
ComboBox cb = sender as ComboBox;
if (cb != null)
{
this.returnedFocus = cb.IsDropDownOpen;
}
}
}
I have a datagrid in WPF with first column as a checkbox. I have now added a select all checkbox which appears on the header of the column that it is bound to.
The handlers for the select all checkbox and individual row check boxes are defined as:
private void SelectAllCheckBox_Checked(object sender, RoutedEventArgs e)
{
foreach (BaseDataItem objItem in BaseReleaseList)
{
objItem.Select = true;
}
BaseReleaseDataGridView.Items.Refresh();
}
private void SelectAllCheckBox_Unchecked(object sender, RoutedEventArgs e)
{
foreach (BaseDataItem objItem in BaseReleaseList)
{
objItem.Select = false;
}
BaseReleaseDataGridView.Items.Refresh();
}
private void RowCheckBoxUnchecked(object sender, RoutedEventArgs e)
{
SelectAllCheckBox.IsChecked = false;
}
private void RowCheckBoxChecked(object sender, RoutedEventArgs e)
{
if (AreAllCheckBoxesChecked())
SelectAllCheckBox.IsChecked = true;
else
SelectAllCheckBox.IsChecked = false;
BaseReleaseDataGridView.Items.Refresh();
}
private bool AreAllCheckBoxesChecked()
{
foreach (BaseDataItem objItem in BaseReleaseList)
{
if (!objItem.Select)
return false;
}
return true;
}
Now the problem is that whenever i click on the select all checkbox or the row check box, control gets stuck inside an infinite loop. Reason is that whenever i set, select to true or false, it again fires an event. How can this be handled.
Instead of tapping two events Checked and UnChecked, register to Click event. Click event will be raised on when user clicks on the checkbox unlike Checked/UnChecked which get called even when you check/uncheck your checkbox programatically.
<CheckBox Name="SelectAllCheckBox" Click="SelectAll_OnClick"></CheckBox>
in handler
private void SelectAll_OnClick(object sender, RoutedEventArgs e)
{
bool? isChecked = SelectAllCheckBox.IsChecked;
if (isChecked.HasValue)
{
foreach (BaseDataItem objItem in BaseReleaseList)
{
objItem.Select = isChecked;
}
BaseReleaseDataGridView.Items.Refresh();
}
}
I have a SelectionChanged event and works perfectly, but I want to figure out how to "catch" this selected item at the click of a button they need to pass it as parameter to another page and edit this Item. Here's the current code and button SelectionChanged I still implemented because this is what I need.
private void listCarros_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ListBox listBox = sender as ListBox;
if (listBox != null && listBox.SelectedItem != null)
{
//pega o Carro que foi selecionado
Carro sCar = (Carro)listBox.SelectedItem;
btnEditCar.IsEnabled = true;
btnDeleteCar.IsEnabled = true;
}
else
{
btnEditCar.IsEnabled = false;
btnDeleteCar.IsEnabled = false;
}
}
I need to edit the selectedItem on this button:
private void btnEditCar_Click(object sender, EventArgs e)
{
//Here I need access to the selectedItem on SelectionChanged event.
}
If you could also tell me how to pass the object as parameter would be perfect.
You can do this with binding also
1.Bind ListBoxItem(Carro Object) to the tag of "btnEditCar" in xaml.
Xaml should be like this
<Button Name="btnEditCar" OnClick="btnEditCar_Click" Tag="{Binding}"/>
and now in
private void btnEditCar_Click(object sender, EventArgs e)
{
Carro sCar=(Carro)((sender as FrameworkElement).Tag)
}
This is the good practice,creating a class variable only for temporary purpose is hack
To give a better idea on my comments. Creating a class level variable is like this:
Notice that sCar is declared outside the method, but within the class.
Carro sCar = new Carro();
private void listCarros_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ListBox listBox = sender as ListBox;
if (listBox != null && listBox.SelectedItem != null)
{
sCar = (Carro)listBox.SelectedItem;
...
private void btnEditCar_Click(object sender, EventArgs e)
{
sCar.ProperyYouWantToChange = "Stuff I want to change"
}
I have been working with Telerik RadGrids and I haven't had any problem setting all items to edit mode when I'm populating the grid.
protected void RadGrid1_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
if (e.Item is GridEditableItem)
{
e.Item.Edit = true;
}
}
Now I'm working with a Telerik RadTreeList and I would like to do something similar. Is it any possible way to do this? As far as I have been searching, I haven't found any possible solution for this.
Did you check at http://www.telerik.com/help/aspnet-ajax/treelist-server-side-basics.html?
RadTreeList has an ItemCreated event as well.
Can you try?
protected void RadTreeList1_ItemCreated(object sender, TreeListItemCreatedEventArgs e)
{
if (e.Item is TreeListDataItem)
{
TreeListDataItem item = e.Item as TreeListDataItem;
item.Edit = true;
}
}
The solution goes as follows:
protected void RadTreeList1_PreRender(object sender, EventArgs e)
{
if (!IsPostBack)
{
foreach (TreeListDataItem item in RadTreeList1.Items)
{
if (item is TreeListDataItem)
{
item.Edit = true;
}
}
RadTreeList1.Rebind();
}
}
The (!IsPostBack) condition would depend on if the TreeListDataItem get's populated at Page_Load.