How to get the context of the button rightclicked - c#

I have encountered some problems in the bookmark section for my wpf web-browser. I want to be able to delete already existing buttons but I can't seem to figure out how to detect the content of the button I right click on. (To get my ContextMenu to show).
My visual progress so far: http://puu.sh/6Dxat.png
Adding a context menu to the buttons:
public void button_MouseRightButtonDown(object sender, MouseButtonEventArgs e)//add a context menu to buttons
{
Button button = sender as Button;
menu = new ContextMenu();
menu.Items.Add(new MenuItem() { Header = "Delete" });
button.ContextMenu = menu;
menu.Closed += button_DeleteButtonClicked;//find the right event
}
(I know that the event is wrong, but that is not important right now.)
And the event:
private void button_DeleteButtonClicked(object sender, RoutedEventArgs e)//delete bookmark
{
//This is where I need help. I want the content (which is the URL) of the button
//right clicked onto, for example, show up in a messagebox. How to do?
}

Since you have hooked Close event of context menu here, so sender will be ContextMenu here and you can get button by using PlacementTarget property of ContextMenu.
private void button_DeleteButtonClicked(object sender, RoutedEventArgs e)
{
Button button = ((ContextMenu)sender).PlacementTarget as Button;
}

Related

ToolStripMenuItem show sub menu on Mouse hover in Windows Forms

I am having a windows form menu strip control. And having ToolStripMenu Item with text of "Click Me". Now i want to display its sub menu toolstrip items on Mouse Hover Event of the "Click Me" ToolStrip. Can any one suggest how its can be done.
Here on mousehover event i want to display its sub menu item like this
You can handle MouseHover event of the items and then using ShowDropDown method, open the dropdown. This way, menus will open on hover rather than click.
For example:
private void Form1_Load(object sender, EventArgs e)
{
this.menuStrip1.Items.OfType<ToolStripMenuItem>().ToList().ForEach(x =>
{
x.MouseHover += (obj, arg) => ((ToolStripDropDownItem)obj).ShowDropDown();
});
}
System.Windows.Forms.ToolStripMenuItem clickmeeToolStripMenuItem
this.clickmeeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem()
this.clickmeeToolStripMenuItem.MouseHover += new System.EventHandler(this.clickmeeToolStripMenuItem_MouseHover);
//ADD THIS METHOD TO YOUR EVENT METHOD
clickmeeToolStripMenuItem.ShowDropDown();

Clicking a ContextMenuItem in a NotifyIcon Context Menu calls the NotifyIcon click Event

I have a WinForms app that starts up in the tray only. On clicking it, it opens a form. This works fine.
notifyIcon.Click += notifyIcon_Click;
//Fires on icon click, AND on contextmenuitem click
private void notifyIcon_Click(object sender, EventArgs e)
{
new ActiveIssues(_hubProxy).Show();
}
I have added a context menu, but when I click the ContextMenuItem, it first fires the NotifyIcon click event, THEN the ContextMenuItem click event, opening both forms.
notifyIcon.ContextMenu = GetCrestContextMenu();
private ContextMenu GetCrestContextMenu()
{
var contextMenu = new ContextMenu();
contextMenu.Name = "CResT Alerts";
contextMenu.MenuItems.Add(GetTextOptionMenuItem());
return contextMenu;
}
private MenuItem GetTextOptionMenuItem()
{
var textOptionMenuItem = new MenuItem { Text = _textOptedIn ? "Opt Out of Text Alerts" : "Opt In to Text Alerts" };
textOptionMenuItem.Click += TextOptionMenuItem_Click;
return textOptionMenuItem;
}
//Fires on menuitem click, after the NotifyIcon click event is called
private void TextOptionMenuItem_Click(object sender, EventArgs e)
{
if (_textOptedIn) new TextOptOut().Show();
else new TextOptIn().Show();
}
Any idea how to either NOT have it fire the notifiyicon click event or to tell that the click was on the context menu?
So it turns out that the right-button click is not registered until after the context menu is clicked, so it is the right-button click that registered and raised the NotifyIcon click event. As such, I had to cast the EventArgs provided for the click as MouseEventArgs, and check the button.
private void notifyIcon_Click(object sender, EventArgs e)
{
if(((MouseEventArgs)e).Button == MouseButtons.Left) new ActiveIssues(_hubProxy).Show();
}

ContextMenu on disabled controls such as buttons

I'm looking for a way to enable/disable buttons using theirContextMenu. But my problem is when I click on the Enable MenuItem to disable the button the ContextMenu won't show anymore.
Is there a way to keep the ContextMenu or other behavior on a disabled Control?
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Enable", new EventHandler(enableButton));
this.button1.ContextMenu = cm;
private void enableButton(object sender, EventArgs e)
{
MenuItem menuItem = sender as MenuItem;
if (menuItem != null)
{
ContextMenu menu = menuItem.GetContextMenu();
Control sourceControl = menu.SourceControl;
sourceControl.Enabled = !sourceControl.Enabled;
}
}
Make your own disabling functionality, set the buttons to grayed out, intercept their events, this way the button will appear disabled but be enabled to receive the ContextMenu event. This behaviour is "By-Design".
You can easily work out the btn.Font to look disabled. For the events one way is to unsubscribe them on Disable, and Hook them up on Enable, here is an example on getting a controls events...
dynamic controltype = btn;
var events = Type.ReflectionOnlyGetType(controltype.AssemblyQualifiedName, false, true).GetEvents();
foreach (var item in events)
{
//EventHandler<T> use a generic Event Handler to Subscribe and Unsubscribe
}
From MSDN
With the Enabled property, you can enable or disable controls at run
time. For example, you can disable controls that do not apply to the
current state of the application. You can also disable a control to
restrict its use. For example, a button can be disabled to prevent the
user from clicking it. If a control is disabled, it cannot be
selected.
and
When a container control has its enabled property set to false, all
its contained controls are disabled, as well. For example, if the user
clicks on any of the controls contained in a disabled GroupBox
control, no events are raised.
So, disabled control cannot raise any events.
You can make your own disable method which make button gayed and disable click events, and reverse enable method.
Based on #esiprogrammer sugestion you can do something like this:
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Point pt = e.Location;
Control ctrl = this.GetChildAtPoint(pt);
if (ctrl != null)
{
ContextMenu menu = ctrl.ContextMenu;
menu.Show(ctrl, new Point(10,10));
}
}
}
there is a workaround to detect right click on mouse up event of form and show context menu. and using this.GetChildAtPoint(e.Location) you can find which control you right clicked on.
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right
&& this.GetChildAtPoint(e.Location)?.Name == "enableButton")
{
ContextMenu.Show();
}
}

How to find in what Panel my button is placed in?

I have some questions that are situated in distinct panels. I place button "Add" in every panel. This button is supposed to add additional textbox to panel. But I don't know what to write in button_click. What panel to choose?
private void button_Click(object sender, EventArgs e)
{
}
Use Control.Parent property.
private void button_Click(object sender, EventArgs e)
{
Button button = sender as Button;
if (button == null)
return; //Some error/exception
Panel parentPanel = button.Parent as Panel;
if (parentPanel == null)
{
//Parent container is not panel
}
//Otherwise get the panel properties.
}
I'll assume all the "Add" buttons are subscribed to this same event.
The value of sender will be the particular "Add" button that was just clicked. Then you can cast the button's Parent to a Panel:
var button = (Button)sender;
var parentPanel = (Panel)button.Parent;
These two lines will be sufficient as long as
You don't accidentally attach some other control other than a button to this event
All the "Add" buttons are contained within a Panel.

How to get the item right clicked on from ContextMenuStrip?

I have a PictureBox.
If I right click the PictureBox, my ContextMenuStrip (right click menu) appears.
In that ContextMenuStrip is a ToolStripMenuItem (one of the options in the right click menu).
There is an event on the ToolStripMenuItem that handles what happens if that option is clicked.
We're starting from ToolStripMenuItem's "Clicked" function. I need to somehow get back to the PictureBox programmatically. From there, I can modify the PictureBox.
ToolStripMenuItem -> ContextMenuStrip -> PictureBox
How would I go about this?
If the click event handler for your menu item is named OnToolStripMenuItemClick, the following might be an approach to your problem:
private void OnToolStripMenuItemClick(object sender, EventArgs e)
{
var menuItem = sender as ToolStripMenuItem;
var contextMenu = menuItem.Parent as ContextMenuStrip;
var pictureBox = contextMenu.SourceControl;
}
Of course, don't forget to check for null when accessing properties after conversion with as.
I'm not sure that I really understood your problem, but I guess you want to let users can return to the picturebox when they want to cancel current operation by clicking the right button. In this case, you should not implement your work in click event, because right and left button both can trigger the click event, instead, you should process your work in the event "MouseUp", like this:
private void menuItemBack_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MessageBox.Show("back item is clicked");
}
else
{
MessageBox.Show("I will come back.");
//do your return things here.
}
}
I've just come across this same problem in C#, and the path to the value seems to be something like:
sender.Owner.SourceControl;
However, since sender, Owner and so on are generic classes, I had to cast everything as follows:
PictureBox pb = (PictureBox) ((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl;
Ugly, but it works.

Categories