Check which submenu item was clicked in context menu strip - c#

There is a ContextMenuStrip in a grid control.
I have named it as GridContextMenu.
The GridContextMenu is populated with 4 - 5 items using the following code :
gridcontextMenu.Items.Add(new ToolStripMenuItem
{
Name = Plants,
Text = Plants,
Tag = Plants,
Width = 100,
Image = <image source is put here>
});
gridcontextMenu.Items.Add(new ToolStripMenuItem
{
Name = Animals,
Text = Animals,
Tag = Animals,
Width = 100,
Image = <image source is put here>
});
For the animal menu in tool strip, i added submenu in the following way
(gridcontextMenu.Items[1] as ToolStripMenuItem).DropDownItems.Add("Tiger", image_source, new EventHandler(SubmenuItem_Click));
(gridcontextMenu.Items[1] as ToolStripMenuItem).DropDownItems.Add("Lion", image_source, new EventHandler(SubmenuItem_Click));
(gridcontextMenu.Items[1] as ToolStripMenuItem).DropDownItems.Add("Elephant", image_source, new EventHandler(SubmenuItem_Click));
In the SubmenuItem_Click event handler i need to know which animal submenu was clicked.
How to achieve this ?
currently i have the code for event handler in the following way :
private void SubmenuItem_Click(object sender, EventArgs e)
{
}
How to check condition in this event that which animal submenu was selected ?
Kindly share the answer.

You can do something like this:
private void SubmenuItem_Click(object sender, EventArgs e)
{
var clickedMenuItem = sender as MenuItem;
var menuText = clickedMenuItem.Text;
switch(menuText) {
case "Tiger":
break;
case "Lion":
break;
. ...
}
}

As I found that none of the other answers worked here, I went digging and found the proper solution. This may have been applicable only in .NET Framework 4+ but here is what I found to work.
Essentially, the ItemClicked event in the ContextMenuStrip control passes itself as the sender and a ToolStripItemClickedEventArgs object when the event is raised. As you can't obtain the clicked item from the ContextMenuStrip itself, the only way to obtain this information is to interrogate the ToolStripItemClickedEventArgs object and the clicked item resides in there as a ToolStripItem object. This can then be used to extract the name of the option to use in an if/switch statement as appropriate. See below:
To configure the EventHandler:
...
contextMenuStrip1.ItemClicked += OnContextMenuItem_Clicked;
...
To handle the event and retrieve the text of the clicked item:
private void OnContextMenuItem_Clicked(object sender, ToolStripMenuItemClickedEventArgs e)
{
ToolStripItem clickedItem = e.ClickedItem;
string itemName = clickedItem.Text;
...
}
Hopefully this helps someone looking for this answer in future :)

You can use Tag for this purpose in case when your should localize your application.
Moreover Tag is an object so you can put any tapy of data there. For example Enum type.
private void SubmenuItem_Click(object sender, EventArgs e)
{
var clickedMenuItem = sender as MenuItem;
EnumType item = (EnumType)clickedMenuItem.Tag;
switch(item) {
case TigeItem:
break;
case LionItem:
break;
...
}
}

This is a way to retrieve the ToolStripMenuItem's index if you have created the ContextMenuStrip Dynamically. It is really helpful with getting Enum values. My Context menu is dynamically created and filled with the Enum Names. I hope it helps someone. Sorry for the formatting still new to posting.
`private void DynamiallyCreatedContextMenu_Click(object sender, EventArgs e)
{
ToolStripMenuItem item = sender as ToolStripMenuItem;
var parent = (item.Owner as ContextMenuStrip);
for (int i = 0; i < parent.Items.Count; i++)
{
if (item == parent.Items[i])
{
index = i;
break;
}
}
}`

private void SubmenuItem_Click(object sender, EventArgs e)
{
string clickedItemName=e.ClickedItem.Text;
}

Related

How to move List View Item from one list to another with drag and drop? UWP C#

I have many List Views in an UWP application and I would want to be able to move one item from one List View to another List View
I know about the AllowDrop or CanDragItems properties and that you need to handle some events for drag and drop to work, although I just don't know how to do it.
If you want to add ListView controls by clicking Add button and move items between ListView controls, please check the following code as a sample. The following code is different from the offical sample, it use ObservableCollection to complete the drag and drop operation. You could drag an item from source ListView item to target ListView, and also drag an item from original target ListView to original source ListView.
You could click the Add button twice and then two ListView with two items are added. You can drag any item from any ListView control to another. If you want to keep the dragged item in the source ListView control, just comment the code dragCollection.Remove(dragedItem as string); .
For example:
private ObservableCollection<string> dragCollection;
private ObservableCollection<string> dropCollection;
private object dragedItem;
private ListView dragListView;
private ListView dropListView;
……
private void AddButton_Click(object sender, RoutedEventArgs e)
{
ListView listView = new ListView();
listView.CanDragItems = true;
listView.CanDrag = true;
listView.AllowDrop = true;
listView.ReorderMode = ListViewReorderMode.Enabled;
listView.CanReorderItems = true;
listView.ItemsSource = new ObservableCollection<string>() { "item1","item2" };
listView.DragItemsStarting += ListView_DragItemsStarting;
//listView.DropCompleted += ListView_DropCompleted;
listView.DragEnter += ListView_DragEnter;
listView.Drop += ListView_Drop;
listView.DragOver += ListView_DragOver;
listView.BorderBrush = new SolidColorBrush(Colors.Red);
listView.BorderThickness = new Thickness(1);
stackPanel.Children.Add(listView);
}
private void ListView_DragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Move;
}
private void ListView_Drop(object sender, DragEventArgs e)
{
dropListView = sender as ListView;
if(dropListView!=null)
{
dropCollection = dropListView.ItemsSource as ObservableCollection<string>;
if (dragedItem != null)
{
dropCollection.Add(dragedItem as string);
//If you need to delete the draged item in the source ListView, then use the following code
dragCollection.Remove(dragedItem as string);
dragedItem = null;
}
}
}
private void ListView_DragEnter(object sender, DragEventArgs e)
{
e.AcceptedOperation = (e.DataView.Contains(StandardDataFormats.Text) ? DataPackageOperation.Move : DataPackageOperation.None);
}
private void ListView_DropCompleted(UIElement sender, DropCompletedEventArgs args)
{
var listView = sender as ListView;
if (listView != null)
{
dropListView = listView;
dropCollection = listView.ItemsSource as ObservableCollection<string>;
if(dropListView==dragListView)
{
return;
}
}
}
private void ListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
var listView = sender as ListView;
if(listView!=null)
{
dragListView = listView;
dragCollection = listView.ItemsSource as ObservableCollection<string>;
if (dropListView == dragListView)
{
return;
}
if(e.Items.Count==1)
{
dragedItem = e.Items[0];
e.Data.RequestedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Move;
}
}
}
For more information about dragging and dropping, you could refer to the document(https://learn.microsoft.com/en-us/windows/uwp/design/input/drag-and-drop).
Any concerns about the code, please feel free to contact me.
To implement dragging, you must set CanDragItems on the source ListView and AllowDrop on the target ListView. Then, you must handle DragItemsStarting event on the source list. Within this handler you can store the dragged data inside the DragItemsStartingEventArgs.Data property. Afterwards, you handle Drop event on the target list and retrieve the stored item values from the DataPackage using DragEventArgs.DataView.
To see all the moving parts of this in action, I recommend the official UWP samples for drag & drop which are available on GitHub. The first scenario of this sample show dragging items from and to a ListView including reordering support.

How to get what form control a context menu was over when clicked one of its items

I‘ve one ContextMenuStrip attached to two controls (DataGridView).
In the ToolStripMenuItem click event, currently I’ve used:this.ActiveControl.Name to get the active GridView control name;
This is fine if I first select the GridView cell and than Rt. click on it to invoke the ContextMenu
Case: sometime if GridView control is not a active control and cell is pre-selected, than context menu Item click not worked accordingly.
Is there any way to get the owner name that initiate the context menu Item click event?
Currently, In the ToolStripMenuItem click event, I've manage to get the original caller (i.e. DataGridView) with this code:
private void CopytoolStripMenuItem1_Click(object sender, EventArgs e)
{
var grid = new DataGridView();
switch (this.ActiveControl.Name)
{
case "dGVEL1":
{
grid=dGVEL1;
break;
}
case "dGVEL2":
{
grid=dGVEL2;
break;
}
}
if (grid == null) return;
DataObject data = grid.GetClipboardContent();
Clipboard.SetDataObject(data);
}
Finally I've Resolved the issue..
The complete solution is
private void CopytoolStripMenuItem1_Click(object sender, EventArgs e)
{
ToolStripDropDownItem item = sender as ToolStripDropDownItem;
if (item == null) // Error
return;
ContextMenuStrip strip = item.Owner as ContextMenuStrip;
var grid = strip.SourceControl as DataGridView;
if (grid == null) // Control wasn't a DGV
return;
switch (grid.Name)
{
case "dGVEL1":
{
grid=dGVEL1;
break;
}
case "dGVEL2":
{
grid=dGVEL2;
break;
}
}
if (grid == null) return;
DataObject data = grid.GetClipboardContent();
Clipboard.SetDataObject(data);
}
Is there any way to get the owner name that initiate the context menu Item click event?
I worked off of the solution you found and simplified it down. Hopefully, this can help some future readers who are looking for a more general solution.
It looks like you go through quite a bit to get ahold of the ContextMenuStrip which is already being passed as sender (granted you will still need to cast it). The following is a more general solution to this issue and it's a bit more simple.
private void contextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {
//Cast the parent as a context menu strip so we can access 'sourceControl' attribute
ContextMenuStrip strip = (ContextMenuStrip) sender;
var stripParent = strip.SourceControl;
//print the name of the 'parent' (Control that called the context menu)
System.Diagnostics.Debug.WriteLine("Called From: " + stripParent.Name);
}

C# how to filter items on ListView using textBox

I want to filter the items that I added to my Listview, using my textbox_TextChanged Can you please show me the Codes, I am using Visual Studio 2013. tia
e.g.
First I am adding a Destination/Regularfare/Discountedfare/Baggagefare to my ListView. and my problem is Searching I want to search the Destinations using a TextBox.
There are no Codes inside my TextBox Search. that one I need.
And here's my Codes for adding an item to my ListView.
public void add(String destination, String Regulare, String Discounted, String Baggage) {
String [] rows = { destination, Regulare, Discounted, Baggage};
ListViewItem item = new ListViewItem(rows);
listView1.Items.Add(item);
}
private void btnAdd_Click(object sender, EventArgs e) {
add(textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text);
textBox1.Text = "";
textBox2.Text = "0";
textBox3.Text = "0";
textBox4.Text = "0";
MessageBox.Show("Record Added!","Saved",MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
tbDestination.Focus();
}
Like the other posters were saying, we don't know what your tech stack is or what problem you're trying to solve. Have you tried binding your list to a data source? Let's say you have a text box and a submit button for filtering. The user enters "California" into the text box and presses submit. You'll have a click handler in the code behind that invokes a DataBind() on your list. The method for your data bind will get the value of the textbox/hidden field and use it to return a conditional data structure that is then used to populate your list. You could even have a clear button that resets the filtering using the same method.
But it's been 16 days now, so you've probably already solved the problem. What did you end up doing?
Hı , Try this two way
First :
private void searchBox_TextChanged(object sender, EventArgs e)
{
// Call FindItemWithText with the contents of the textbox.
ListViewItem foundItem =
textListView.FindItemWithText(searchBox.Text, false, 0, true);
if (foundItem != null)
{
textListView.TopItem = foundItem;
}
}
Second :
void yourListView_MouseDown(object sender, MouseEventArgs e)
{
// Find the an item above where the user clicked.
ListViewItem foundItem =
iconListView.FindNearestItem(SearchDirectionHint.Up, e.X, e.Y);
if (foundItem != null)
previousItemBox.Text = foundItem.Text;
else
previousItemBox.Text = "No item found";
}

c# xaml selecting controls using Name

I have the following dispatch routine in VS2013 C#:
private void B_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
string src = btn.Name.ToString();
string foo = "G" + src.Substring(1);
G0.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
It currently changes the visibility of G0. I want to change the code so that if Button B123 is pressed, then G123.Visibility is changed.
Thanks,
Dan
Note: This is a generic eventhandler for the buttons. There are 100's of buttons so an individual handler for each button is not practical. It could also be the handler from a dropdown or text box. G123 is a random control on the XAML page. The point is, given a string that contains the Name, how do I find the associated control so that I can modify its properties?
I'm not sure that I correctly understand your question, so I may be guessing that if button buttons B123 and G123 are related to each other by the number 123. In general, I suppose you want to change the visibility of button GX if button BX is changed.
In order to find all controls in the Window, have a look at the solution provided by Bryce Kahle, see Find all controls in WPF Window by type. In your buttenclick handle, do something like
private void B_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
string src = btn.Name.ToString();
string identifier= src.Substring(1);
foreach (var btn in FindVisualChildren<Button>(this).Where(b => b.Name.EndsWith(identifier)))
{
if(btn.Name.StartsWith("G"))
btn.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
}
Hope that helps.
In the comments, user Clemens gave the answer. (Since he didn't give it as an answer, I can't vote it up.)
Using FindName, I was able to get to the properties of the desired control:
private void B_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
string src = btn.Name.ToString();
string foo = "G" + src.Substring(1);
Windows.UI.Xaml.Shapes.Rectangle rect = (Windows.UI.Xaml.Shapes.Rectangle)this.FindName(foo);
rect.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
This has the flexibility so that I can change the fill, contents, text, foreground, style, etc. for a specified control. More control than if I had simply used XAML binding.
Thanks Clemens,
Dan

Getting the control of a context menu

I have a context menu that looks like this
A
|--1
|--2
|--3
I need to access the object that the context menu is called from, after selecting 1 2 or 3
meaning if this is a context menu of a textbox1 then I need to access that object, how do I do that?
Forgot to mention, this is a WPF application. so Im using the System.Windows.Controls
and the ContextMenu is created programmatically
You can walk up the tree and get the control from the ContextMenu.PlacementTarget, e.g.
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
var item = sender as MenuItem;
while (item.Parent is MenuItem)
{
item = (MenuItem)item.Parent;
}
var menu = item.Parent as ContextMenu;
if (menu != null)
{
var droidsYouAreLookingFor = menu.PlacementTarget as TextBox;
//...
}
}
You can look at the SourceControl property of the ContextMenuStrip that owns the context menu item that was clicked.
For example, in the Click handler for the menu item:
private void aToolStripMenuItem_Click(object sender, EventArgs e)
{
var control = ((sender as ToolStripMenuItem).Owner as ContextMenuStrip).SourceControl;
...
}
Of course if you only have one ContextMenuStrip on the form, you can just reference it directly
var control = myContextMenuStrip.SourceControl;
Slight tweak to HB's answer. HB deserves the credit. Helped me find a DataGrid.
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
ContextMenu cm = (ContextMenu)item.Parent;
Popup popup = (Popup)cm.Parent;
var finalGoal = popup.PlacementTarget as DataGrid;
}
use the
ContextMenu.SourceControl
that's the variable that calls the context menu. all you need to do is cast the control
found the answer from a similar question
Get owner of context menu in code
viky's code works, but I had to cast it twice.
I guess looping the casting of the Parent is possible for better flexibility
(more casts depends on how deep the clicked item is)
Ugly Solution
I am searching for a better way to do the same thing. For now, the code below works:
TextBlock tb = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBlock;
Replace TextBlock with your control's type.

Categories

Resources