Troubles with updating ToolstripDropdownButton after window loses focus - c#

Let me start from a simple example to reproduce my problem:
Create WinForms project.
Drop a ToolStrip on it.
Make a ToolstripDropdownButton in it (with no children).
Add a click event-handler to the button, with something like this:
MessageBox.Show("text", "Caption");
(the point is to make the main form loose it's focus).
To make the problem more obvious, let's make a few unnecessary additions:
Set RenderMode of our ToolStip to ManagerRenderMode.
Set it's Autosize to false and make it a lil bigger.
And that's should be enough to reproduce it. Run the app and click the Button. You'll get the popup. Close the popup and voila ... the button now looks like someone is holding it pressed.
Any ideas on how to reset it to it's default state?
I've tried to call Buttons ResetBackColor, Refresh ... also as ToolStrips. Doesn't seem to work. Maybe I'm missing something?

The MessageBox or a modal form will interfere with that. The drop down is expecting children menu items.
Sample work around:
private void toolStripDropDownButton1_Click(object sender, EventArgs e) {
this.BeginInvoke(new Action(() => MessageBox.Show("Help")));
}

Related

C# Tabcontrol messed up my form

I had a form made up with buttons, textboxes, and labels. Then I decided to see if I could use tab control because I wanted to add other buttons but I didn't want them to be on the same page. So I cut all my buttons and textboxes and labels and I paste the tabcontrol. Then I paste all of the buttons and stuff back on in tab1. So before I moved on to making buttons I decided to test run the program. I got a page that came up and said nullreferenceexeption was unhandled. When I tried clicking on one of my button, I saw that there was no code inside it and it went from
private void Button1_Click(object sender, EventArgs e)
to
private void Button1_Click_1(object sender, EventArgs e)
Then the errors kept coming up. Now I just want to make my form the way it was before but even though I deleted the tabcontrol, when I click my buttons they still have the _Click_1 thing. Please tell me how I can fix this. I am new to C# so try to explain it simply.
And if you can, tell me how I can add the tabcontrol thing without messing up my entire program.
Also is there a way I could like roll back changes for a day or 2 in visual studio ultimate? Please get back as soon as possible I'm ripping my hair out I can't lose the program I've been working on for 2 weeks.
You can fix most of these problems, but it's going to take a bit of work. For each button, open the properties tab and go to the events section, find the event Click and click once in the text field. You should see a drop down arrow, click that arrow and look at the list. Find the event you expect the button to fire and click on it (Hint : it doesn't have _1 at the end)

Cycling through TabControl tabs while not having focus on it

I started with my first WinForms project, and bumped into a small problem on the way.
I have a Form with a TabControl and some buttons outside it.
The problem is when i have a button focused and press Ctrl-Tab - nothing happens. But if you open, for instance, properties window of a file in explorer, you can cycle through tabs using Ctrl-Tab no matter which element has the focus.
So what is the right way to make such behavior? I mean, i can do Form.KeyPreview = true and write handlers myself, but is there a better way to do this?
As far as I know, the correct way is the one you mentioned yourself i.e. set Form.KeyPreview = true and write private Form1_KeyDown(object sender, KeyEventArgs e) handler to switch tabs.

Windows form has focus but doesn't process keyboard events

I have a strange problem:
I have a Form that I open using ShowDialog(). The form is populated with some buttons and comboboxes. One of the comboboxes is set as the ActiveControl of the Form and the Form has focus.
What I want to accomplish is that the user can enter its username immediately after the Form opens (without the need to select the combobox first). However, if I press the keyboard, nothing happens. However, when I first click on the form with the mouse, and then enter something using the keyboard, it works. I already tried a lot of things like calling Select() and Focus() on the form. I even tried to simulate a mouseclick event (OnMouseClick) on the Form without any luck.
Someone has an idea would could be the problem here?
many thanks
Chris
Try BringToFront()
var f = new Form1();
f.Show();
f.BringToFront();
Then just use Select on that control
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.Select();
}
Assuming you're running ShowDialog() from another form it might be worth changing it to: ShowDialog(this) so the new form has the correct parent and the correct blocking behaviour. Without the 'this' I've seen forms open up behind other forms and other strange behaviour, including focus problems.
Just a thought.
Have you tried calling myComboBox.Focus();
Just because the form has focus doesn't necessarily mean any control within the form has focus. Also try checking the onKey events of both the form and the individual controls. This normally helps me diagnose what exactly has focus. If the form itself and non on its controls are getting any onKey events then try using form.Activate();

How to get system tray functionality WITHOUT using NotifyIcon.ContextMenu?

I'm trying to get my application to display a popup context menu when a user right-clicks on my notify icon in the system tray... but there's a twist.
I'm aware that the NotifyIcon class I'm using to get the icon in the system tray has a ContextMenu property. I don't want to use that to get a right-click popup menu, because it ALWAYS displays a right-click popup menu, and never does anything else. When my main form is displaying a modal dialog, I want right-click to activate the main form, NOT display a popup menu.
So, I'm guessing I need to use the NotifyIcon.MouseClick event, and manually pop up the menu in that event? Here's where I've got to so far:
private NotifyIcon trayIcon;
private ContextMenu iconMenu;
private void frmMain_Load(object sender, EventArgs e) {
// [...]
this.trayIcon.MouseClick += new MouseEventHandler(trayIcon_MouseClick);
iconMenu = new ContextMenu();
// [...]
}
private void trayIcon_MouseClick(object sender, MouseEventArgs ea) {
this.iconMenu.Show(Program.instanceFrmMain, new Point(System.Windows.Forms.Cursor.Position.X - Program.instanceFrmMain.Left, System.Windows.Forms.Cursor.Position.Y - Program.instanceFrmMain.Top));
}
Notice how in iconMenu.Show, because it takes popup co-ordinates relative to the parent control (my main form here), I'm annoyingly having to subtract the parent control's co-ordinates from popup co-ordinates, something I already don't want to have to do.
Apart from that, here are the problems I'm having:
Although the menu does popup on right-click, it doesn't close if I click somewhere else on the screen outside the menu - and it should.
The menu doesn't quite popup in the right location; for other system tray apps, it pops up so its bottom-right or bottom-left corner are at the tip of the mouse cursor. For mine, the popup menu is at the base of the screen, to the side of the mouse cursor.
Any ideas how I can get this to work better? I know it's possible, plenty of other apps manually handle the displaying of a popup menu manually instead of using some NotifyIcon.ContextMenu property.
Use the ContextMenuStrip property rather than ContextMenu. The ContextMenuStrip class has an Opening event, which you can cancel by setting e.Cancel = true. That way you don't have to worry about the location of the menu, since it is automatically handled
OK, well I didn't manage to get the functionality I wanted as I described in the original question, but I have managed to find a way to achieve the desired effect using a different method.
I DO attach a ContextMenu to the trayIcon.ContextMenu property, but I attach event handler code to the Popup property of the context menu itself. If, in that handler, I .Clear the ContextMenu, it actually doesn't appear at all, allowing my code to elect to effectively stop the trayicon's popup menu from showing if it wants to. This was the effect I was looking to achieve. If I populate the ContextMenu in the Popup event handler code instead, the menu pops up as usual containing what I populated it with.
Sooo, I managed to solve the problem a different way. :-)

How to do two things with one click in Windows Form

On my main form, there is another (floatable) window. This floatable window works sort of like a popupwindow in that it will close when the user clicks somewhere else outside of this window. This is handled by the Deactivate event. But what I want to do is, if the user clicks on a different control (say a button), I want to both close this float window and then activate that button with just one click. Currently, the user has to click twice (one to deactivate the window and once more to activate the desired button). Is there a way to do this with just one click?
foreach(Control c in parentForm.Controls)
{
c.Click += delegate(object sender, EventArgs e)
{
if(floatyWindow != null && floatyWindow.IsFloating)
{
floatyWindow.Close();
}
};
}
And then add your handlers as normal. This additional handler can close the floaty window.
Make sure you floaty window isn't a dialog too as this will not allow your parent form's controls to be clicked.
I had a slightly hacky solution. In your Deactivate event, fire another custom event to your main form. Then when you main form is handling the custom event, enumerate through your control(this.Controls) and locate the control under the mouse by checking all their bound then call Focus(). You might need to sort by the one with the smallest surface area, or you can have a separate list of "focus-able" control like button just for this purpose.
Another way might be to switch focus to your main form immediately after OnMouseLeave of the floatable window, or OnMouseHover of your main window, but keep the floatable windows on top, just no focus. Handle the global mouse down of your main form, and close the floatable window by then.
These are just theories, not tested.
I had an issue like this once too, when a customer wanted "floaty" windows all over there application. I used used an approach similar to the one described in this article:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/article.asp
Code sample available here:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/Popup_Form_Demonstration.asp
By extending this a bit we created "floaty" windows similar to the ones VS uses when you get a runtime error while debugging code.
At the very least reading the code may give you some insight, however, quarrelsome's response may be the more simple solution.

Categories