toolstripmenu handle drop down - c#

I have toolstrip menu item with some other toolstrip menu items under it. How can i handle first toolstrip menu (parent) for not opening and showing children if some condition is met.
So i have:
Documents: (parent toolstrip item)
----Document1 (child)
----Document2 (child)
----DOcument3 (child)
and on documentsToolStripMenuItem_Click(object sender, EventArgs e) i have
if(CurrentUser.HasPermission(0001))
{
MessageBox.Show("You do not have permission to access this module!");
//Here i need to prevent showing children of this parent
}
So to sum up, user need permission to press parent toolstrip menu item (documents) and when he press it and doesn't have premission i do not want to let him see what is under that parent (it's children).
I know i can make that toolstripmenu hidden or enabled = false but i have other things because of what it needs to be clickable.

You would have to use the DropDownOpening event:
void parentItem_DropDownOpening(object sender, EventArgs e) {
allowedItem.Visible = true;
notAllowedItem.Visible = false;
}

Related

Access controls located on the main form when the child form closes

I have created a main form which is always visible to users... its got some menu options. This form (Main) has got a number of hidden buttons which I am trying to unhide from another child form once the child form closes. My question is..."how do you transfer control from child to Main or reference the buttons on the Main form once the child have close. Thanks in advance for all help and suggestions. Here is what I have got so far:-
//This event is in the child's form..
private void Registerbutton_Click(object sender, EventArgs e) {
.
. // carry out some work and close
.
}
this.Close();
Showbuttons();//custom procedure
//custom procedure use to display all the hidden buttons on Main form
public void Showbutton(){
foreach (Control c in ((Main)MdiParent).Controls){
if (c is Button){
((Button)c).Show();
}
}
}
Subscribe to the child form's FormClosed event:
var childForm = new ChildForm();
childForm.FormClosed += ChildFormClosedHandler;
childForm.Show();
Then once the child form closes it will show all the buttons that are direct descendants of the form.
private void ChildFormClosedHandler(object sender, FormClosedEventArgs e)
{
foreach (Button button in this.Controls.OfType<Button>()){
button.Visible = true;
}
}
If you only want the buttons to be shown after some specific function then you may need to set some property on the child and do a check through the sender argument.

ToolStripMenuItem ShowDropDown - event doesn't fire

I want to put a context sensitive menu on the right-click of a DataGridView. I want to have a single menu item derived from the content of the clicked cell and a variable number of items in a sub-menu, retrieved from a database.
I do this by building the ToolStripMenuItem in the ContextMenuStrip Opening event. And it works - almost...
If I leave the sub-menu undisplayed so the user has to click the single item in the toplevel menu, everything is fine but if I call the ShowDropDown method to display the submenu automatocally, the exents don't fire when the items are clicked on.
Here's the simplest code I can produce to recreate the problem - I've pulled out all the references to the DataGridView and database so my "dynamic" menu is decidedly static ;-)
If you put this is a Form definition, right-click anywhere on the form and you'll see the working but not desired behaviour - click on a sub-menui tem and see a popup. Tick the checkbox and right-click again and you'll see the submenu flies out automatically - but clicking items won't fire the aliasClick handler.
Any thoughts? In this particular application, I can code a perfectly servicable workaround which avoids using ShowDropDown - but I'd like to know what I'm doing wrong in case I need to use it in future.
public partial class Form1 : Form
{
private ContextMenuStrip cms;
private CheckBox chkAuto;
public Form1()
{
InitializeComponent();
chkAuto = new CheckBox();
Controls.Add(chkAuto);
cms = new ContextMenuStrip();
cms.Opening += contextMenuStrip1_Opening;
this.MouseClick += Form1_MouseClick;
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
cms.Show(Cursor.Position);
}
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
cms.Items.Clear();
ToolStripMenuItem tsmi = new ToolStripMenuItem("Title from datagridviewcell");
tsmi.DropDownItems.Add(new ToolStripMenuItem("First item from database lookup", null, aliasClick));
tsmi.DropDownItems.Add(new ToolStripMenuItem("Second item from database lookup", null, aliasClick));
tsmi.DropDownItems.Add(new ToolStripMenuItem("Last item from database lookup", null, aliasClick));
cms.Items.Add(tsmi);
if (chkAuto.Checked)
tsmi.ShowDropDown();
e.Cancel = false;
}
private void aliasClick(object sender, EventArgs e)
{
ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
MessageBox.Show(clickedItem.Text);
}
}
I'm not entirely sure how to go about proving this, but I suspect that your call to tsmi.ShowDropDown() is somehow causing the coordinates to not be captured properly by the click handler. Replace it with cms.Show(MousePosition) and it works.
Perhaps some useful info gleaned from a look at the coordinates...
var mi = new ToolStripMenuItem("First item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi);
var mi2 = new ToolStripMenuItem("Second item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi2);
var mi3 = new ToolStripMenuItem("Last item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi3);
cms.Items.Add(tsmi);
if (chkAuto.Checked)
tsmi.ShowDropDown();
//cms.Show(MousePosition);
Debug.WriteLine(mi.Bounds.ToString());

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.

c# winforms context menu events problem

I added a context menu (add, cancel) to tree view dynamically. Now I want to show the selected tree node value when I click on context menu item click.
How can I do that?
I assume you want to know which node was right-clicked when the context menu is opened?
To determine this you can handle the mousedown event on the treeview and ensure the node you right-clicked is selected before the context menu is displayed.
private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var node = treeView1.HitTest(e.X, e.Y).Node;
treeView1.SelectedNode = node;
}
}
In the ToolStripMenuItem's click handler you can check treeView1.SelectedNode, it will be null if the user right clicked the treeview outside a node.
private void addToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeView1.SelectedNode != null) MessageBox.Show("Node selected: " + treeView1.SelectedNode.Text);
}
I assume you just need to know the text of the treenode? This code should do the job
string treeNodeText = this.treeView1.SelectedNode.Text;

Categories