I have 2 project in my solution on Visual Studio. First project (Winforms/Application) has got a notify icon with content menu strip like this:
private void TrayMenuContext()
{
notifyIcon1.ContextMenuStrip = new ContextMenuStrip();
notifyIcon1.ContextMenuStrip.Items.Add("Test1", null, MenuTest1_Click);
notifyIcon1.ContextMenuStrip.Items.Add("Test2", null, MenuTest2_Click);
notifyIcon1.ContextMenuStrip.Items.Add("Exit", null, MenuExit_Click);
}
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
var mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
mi?.Invoke(notifyIcon1, null);
}
}
And the second project (Winforms/Application) has got a button like this:
private void button1_Click(object sender, EventArgs e)
{
/*
* How should I code here to delete the notify icon content menu strip item
* in first application named "Test2"?
*/
}
When I click the button, I want to delete the "Test2" menu item in the first application notify icon content menu strip. But unfortunately I don't have the slightest idea about it. Moreover, I do not know if such a thing is possible. However, the extraordinary features of .Net encourage me.
Related
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());
What i tried now is in the richTextBox1 mouseup event and also the events for each action:
private void richTextBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
ContextMenu contextMenu = new System.Windows.Forms.ContextMenu();
MenuItem menuItem = new MenuItem("Cut");
menuItem.Click += new EventHandler(CutAction);
contextMenu.MenuItems.Add(menuItem);
menuItem = new MenuItem("Copy");
menuItem.Click += new EventHandler(CopyAction);
contextMenu.MenuItems.Add(menuItem);
menuItem = new MenuItem("Paste");
menuItem.Click += new EventHandler(PasteAction);
contextMenu.MenuItems.Add(menuItem);
richTextBox1.ContextMenu = contextMenu;
}
}
void CutAction(object sender, EventArgs e)
{
richTextBox1.Cut();
}
void CopyAction(object sender, EventArgs e)
{
Clipboard.SetData(DataFormats.Rtf, richTextBox1.SelectedRtf);
Clipboard.Clear();
}
void PasteAction(object sender, EventArgs e)
{
if (Clipboard.ContainsText(TextDataFormat.Rtf))
{
richTextBox1.SelectedRtf
= Clipboard.GetData(DataFormats.Rtf).ToString();
}
}
There are two problems:
When i mark text in the rcihTextbox and make right click nothing happen only when i make another right click i see the menu Cut Copy Paste. Why it's not showing the menu on the first right click ?
Second problem when i make Copy click on Copy then i go to the chrome browser and try to make paste it's empty the paste is empty like it didn't copy it at all.
I checked now again only Cut is working. If i make Copy it's not copying anything and i can't paste into Chrome address bar at top. Or if i copied from exmaple from chrome something i searched for: hello world then the Paste in the richTextBox is empty.
I want to be able to copy/cut/paste from inside the richTextBox control it self and from other external programs like notepad chrome ie or even other richtextbox control.
The ContextMenu is not showing because you set it after the right click. Try to set it on the MouseDown event. When you click copy, you set the text in the clipboard but you remove it after with the Clipboard.Clear(), so i don't know what you were thinking by writing this line, just remove it.
this is my code:
public RegForm()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void label10_Click(object sender, EventArgs e)
{
}
private void label28_Click(object sender, EventArgs e)
{
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
}
private void label29_Click(object sender, EventArgs e)
{
}
private void label30_Click(object sender, EventArgs e)
{
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
}
I would like to remove all the unnecessary lines of code for the labels that just came up out of nowhere for no reason and do absolutely nothing. But when I delete them - it's all errors. I'm a beginner, so please go easy on me. Thank you in advance.
To remove those empty event handlers:
Switch to the designer view,
Select each label, one at a time,
Look at the properties window (press F4 if it's not visible), and check out the events view
Find the click event, right-click and choose "reset".
Be careful when you're selecting your different controls in the designer.
If you double-click by accident, you end up creating an empty event handler for whatever the default event is for a particular control. In the case of a Label, it happens to be the Click event.
This are auto generated events which are created when you double click
on control or some other action is performed on the controls in the
design view.
Remove the lines from code behind and also remove them from *.designer.cs file.
IF you build the application after the removing of the lines and check errors: You can click on every error and it will leads you to the place which should be deleted !
If those are unnecessary then just go ahead and delete them from your code behind *.cs file. You will also have to delete the event registration from the corresponding *.designer.cs file and because of the same thing you are getting error (that you are not removing the corresponding event registration from designer file).
You can as well do the same from Designer window by select the control -> press F4 -> go to the event pane by clicking the lighting bolt icon -> remove the event registration.
Is there an easy way to show an dialog when the program is started for the first time (and only the first time), for some kind of instruction or specifying settings?
You could save it as a bool in your settings and you should check at load event of first form.
Your settings file should have a setting that I called "FirstRun" do this with following steps:
Right click your Project
Click "Properties"
Click "Settings" tabpage(probably on the left)
Add setting like I did as seen in image above
Note: The Scope can be changed to "Application", if that is your application's need, since you didn't mention in your question.
Your Settings file should look like image below:
public void Form1_Load(object sender, EventArgs e)
{
if((bool)Properties.Settings.Default["FirstRun"] == true)
{
//First application run
//Update setting
Properties.Settings.Default["FirstRun"] = false;
//Save setting
Properties.Settings.Default.Save();
//Create new instance of Dialog you want to show
FirstDialogForm fdf = new FirstDialogForm();
//Show the dialog
fdf.ShowDialog();
}
else
{
//Not first time of running application.
}
}
Note: wrote this from my phone, so I couldn't compile to test
Edit: Checked code and added image from desktop.
You can have bool value in your settings file which is a "user setting" which means you can change it to true save it for this specific user.
When your application starts just check that value. If it's false show your dialog and change it to true and it will stay true.
public void Form_Load(object sender, EventArgs e)
{
if(Settings.Default.ShowDialog)
{
Settings.Default.ShowDialog = false;
Settings.Default.Save();
// show first disalog
}
// rest of code if needed
}
Here's an MSDN link on user settings:
http://msdn.microsoft.com/en-us/library/bb397750(v=vs.110).aspx
Ok, so I assume you're creating WinForms application. First of all, locate the Load event in your main Form event lists (or simply double click your Form in Designer panel). The following method stub will pop up:
public void Form1_Load(object sender, EventArgs e)
{
}
And modify it like this:
public void Form1_Load(object sender, EventArgs e)
{
MessageBox.Show("Your message here");
}
With C# I am trying to only show a ContextMenuStrip (CMS) when I right click a specific column in my DataGridView. I am confused as to whether I should be using a DataGridView_CellContentClick and/or dataGridView1.HitTest(). Then to finish off my problem I want to send the data from that right clicked cell to a new form window.
My current code has strange behavior. It will not show the CMS unless I have first left click or right clicked the 4th column. However once I have it will always show the CMS on a right click.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 4)
{
//Create the ContextStripMenu for Creating the PO Sub Form
ContextMenuStrip Menu = new ContextMenuStrip();
ToolStripMenuItem MenuOpenPO = new ToolStripMenuItem("Open PO");
//Assign event handlers
MenuOpenPO.MouseUp += new MouseEventHandler(MenuOpenPO_Click);
Menu.Items.AddRange(new ToolStripItem[] { MenuOpenPO });
//Assign created context menu strip to the Datagrid
dataGridView1.ContextMenuStrip = Menu;
}
}
void MenuOpenPO_Click(object sender, MouseEventArgs e)
{
var ht = dataGridView1.HitTest(e.X, e.Y);
MessageBox.Show("Hello2");
PO_Form POWindow = new PO_Form();
POWindow.Show();
}
I was going to use the var ht = dataGridView1.HitTest(e.X, e.Y); to grab the cell value.
Any help would be appreciated, thanks!
Edit 1
So I updated dataGridView1_CellContentClick to this and it gets me very close to the behaviour I am looking for. If I first left click in column 4 then right click I get my CMS. If I left click any other cell in another column then right click the CMS is no longer there. However I want to be able to just right click a cell in column 4 without having to left click first to create the CMS.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 4)
{
//MessageBox.Show("Hello1");
//Create the ContextStripMenu for Creating the PO Sub Form
ContextMenuStrip Menu = new ContextMenuStrip();
ToolStripMenuItem MenuOpenPO = new ToolStripMenuItem("Open PO");
//Assign event handlers
MenuOpenPO.MouseUp += new MouseEventHandler(MenuOpenPO_Click);
Menu.Items.AddRange(new ToolStripItem[] { MenuOpenPO });
//Assign created context menu strip to the Datagrid
dataGridView1.ContextMenuStrip = Menu;
}
else
dataGridView1.ContextMenuStrip = null;
}
I did this in VB ..
Private Sub DGV_CellMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DGV.CellMouseClick
If e.Button = Windows.Forms.MouseButtons.Right Then
DGV.CurrentCell = DGV.Rows(e.RowIndex).Cells(e.ColumnIndex)
CMS.Show(DGV, DGV.PointToClient(Windows.Forms.Cursor.Position))
End If
End Sub
I figured out my own problem and so will post the solution. Unfortunately I am very new at C# programming and really extremely rusty at it in general. I struggled with the concept of Event handlers (not sure if correct name?), how they were being called and how they all vary depending on if you are using MouseEventArgs, EventArgs, KeyEventArgs, etc. Anyway I digress.
My solution is below. I found the using dataGridView1.MouseUp gave me poor user interaction results requireing 2 of each action for a state change. IE create my ContextMenuStrip when the correct coloumn is right Clicked. Or make it disappear if any other column is right clicked. So use dataGridView1.MouseDown for better results.
dataGridView1.MouseDown += new MouseEventHandler(this.dataGridView_MouseDown);
private void dataGridView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var ht = dataGridView1.HitTest(e.X, e.Y);
if (ht.ColumnIndex == 4)
{
//Create the ContextStripMenu for Creating the PO Sub Form
ContextMenuStrip Menu = new ContextMenuStrip();
ToolStripMenuItem MenuOpenPO = new ToolStripMenuItem("Open PO");
MenuOpenPO.MouseDown += new MouseEventHandler(MenuOpenPO_Click);
Menu.Items.AddRange(new ToolStripItem[] { MenuOpenPO });
//Assign created context menu strip to the DataGridView
dataGridView1.ContextMenuStrip = Menu;
}
else
dataGridView1.ContextMenuStrip = null;
}
}
If you want to create a new form or do something else I used the following code when clicking your ContextMenuStrip I used the following after creating this event handler? MenuOpenPO.MouseDown += new MouseEventHandler(MenuOpenPO_Click);
void MenuOpenPO_Click(object sender, MouseEventArgs e)
{
PO_Form POWindow = new PO_Form();
POWindow.Show();
}