Autohide MenuStrip - How to activate it when showing? - c#

I have a MenuStrip and I make it AutoHide using following code. It hides/shows prefect but when a control get focus, by pressing Alt key, MenuStrip shows but it is not active and there is not small underline under shortcut keys for example under 'F' for File , and pressing 'F' will not open it). How can I correctly active it?
Note: I used MenuDeactivate instead of it but it did not work prefect.
bool menuBarIsHide = true;
bool altKeyIsDown = false;
bool alwaysShowMenuBar=false;
//KeyPreview is true;
//for prevent glitch(open/close rapidly)
void Form1_KeyUp(object sender, KeyEventArgs e)
{
if ((Control.ModifierKeys & Keys.Alt) != 0)
altKeyIsDown = false;
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
if ((Control.ModifierKeys & Keys.Alt) != 0)
{
if (altKeyIsDown)
return;
if (!alwaysShowMenuBar)
{
if (menuBarIsHide)
{
menuBar.Show();
menuBarIsHide = false;
//manage container height
}
else
{
menuBar.Hide();
menuBarIsHide = true;
//manage container height
}
}
}
}

You can override ProcessCmdKey to handle Alt key to toggle the menu visibility. Also to activate menu, call internal OnMenuKey method of MenuStrip. Also handle MenuDeactivate to make the menu invisible after finishing your work with menu, but you need to make the menu invisible using BeginInvoke.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Alt | Keys.Menu))
{
if (!this.menuStrip1.Visible)
{
this.menuStrip1.Visible = true;
var OnMenuKey = menuStrip1.GetType().GetMethod("OnMenuKey",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
OnMenuKey.Invoke(this.menuStrip1, null);
}
else
{
this.menuStrip1.Visible = false;
}
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void menuStrip1_MenuDeactivate(object sender, EventArgs e)
{
this.BeginInvoke(new Action(() => { this.menuStrip1.Visible = false; }));
}

Related

Capturing Ctrl+A shortcut key

I need to capture a kepress combo on the keyboard so i can override the standard function, i've tried the following:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
{
MessageBox.Show("Hello");
}
}
But when pressing Ctrl+A the message is not triggered. The end aim is to override the windows shortcut 'select all' in a DataGridView within the Form1 to ensure only certain rows are selected when Ctrl+A is pressed in the form window.
First, ensure that Form1 property
KeyPreview = true
Next, do not forget to handle the message (you don't want DataGridView process the message and do SelectAll)
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
{
e.Handled = true; // <- do not pass the event to DataGridView
MessageBox.Show("Hello");
}
}
So you preview KeyDown on the Form1 (KeyPreview = true), perform the required action, and prevent DataGridView from executing select all (e.Handled = true)
In general to handle a shortcut key, you can override ProcessCmdKey. By overriding this method, you can handle the key combination:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.A))
{
MessageBox.Show("Control + A");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Returning true, means it's handled by your code and the key will not pass to the child control. So it's enough to override this method at form level.
But if you are talking specifically about DataGridView to customize the Ctrl + A combination, you can override ProcessDataGridViewKey method of the DataGridView:
public class MyDataGridView : DataGridView
{
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyData == (Keys.A | Keys.Control))
{
MessageBox.Show("Handled");
return true;
}
return base.ProcessDataGridViewKey(e);
}
}
Just for the records: This can be done with KeyPress too, because the Ctrl+Letter keys are "special":
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar=='\u0001') //Ctrl+A, B=2, C=3 ...
{
MessageBox.Show("Control + A");
}
}

Focus changes even after setting e.Handled = true

I've set KeyPreview = true; for my Form. I basically want to use the arrow keys to go to the next and previous images instead of changing focus to different controls. I've set the Handled property to true but still the focus changes on arrow key press.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
// Do stuff
}
else if (e.KeyCode == Keys.Left)
{
// Do stuff
e.Handled = true;
}
else if (e.KeyCode == Keys.Right)
{
// Do stuff
e.Handled = true;
}
}
EDIT
The behavior I want to achieve is as follows.
Left Arrow Key -> Previous Image
Right Arrow Key -> Next Image
Now, I also have a few TextBoxes on my Form and I therefore do not want to go to next and previous images if those Textboxes are in focus because then it should navigate through the text instead.
This worked for me.
Do not set KeyPreview = true; for the Form.
Override ProcessCmdKey and process as needed if any of the TextBoxes do not have focus.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (textBox1.ContainsFocus || textBox2.ContainsFocus || textBox3.ContainsFocus)
{
return base.ProcessCmdKey(ref msg, keyData);
}
if (keyData == Keys.Delete)
{
removeRect();
return true;
}
else if (keyData == Keys.Left)
{
previousImg();
return true;
}
else if (keyData == Keys.Right)
{
nextImg();
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}

KeyPress F1 does not work C#

I'm designing a device app. Compact Framework 2.0
I want the user to press F1 to navigate to the next screen, but it does not work.
Can't seem to find a solution.
Is it possible?
This is how I normally use Keypress:
This works:
if (e.KeyChar == (char)Keys.M)
{
MessageBox.Show("M pressed");
e.Handled = true;
}
This dos NOT work:
if (e.KeyChar == (char)Keys.F1)
{
MessageBox.Show("F1 pressed");
e.Handled = true;
}
try this
private void Form1_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.ToString() == "F1")
{
MessageBox.Show("F1 pressed");
}
}
Refer This
You can override the ProcessCmdKey method of your form class and use keyData == Keys.F1 to check whether F1 is pressed. Above link has example as follows.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.F1)
{
MessageBox.Show("You pressed the F1 key");
return true; // indicate that you handled this keystroke
}
// Call the base class
return base.ProcessCmdKey(ref msg, keyData)
}
Some keys(like f1,f2,arrow keys ,tab ....)cannot be "captured" by keychar for that you need to use keycode:
if (e.KeyCode == Keys.F1)
{
// do stuff
}
keychar property - http://msdn.microsoft.com/en-us/library/system.windows.forms.keypresseventargs.keychar.aspx
Use KeyDown instead of KeyPress:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.F1)
{
// your code here
}
}
Also set KeyPreview to true

how to disable copy, Paste and delete features on a textbox using C#

Can anybody please suggest how to handle Cut,Copy and Paste events on a Text Box in WinForms using C#?
In WinForms, the easiest way to disable cut, copy and paste features on a textbox is to set the ShortcutsEnabled property to false.
You'd have to subclass the textbox and then override the WndProc method to intercept the windows messages before the control does.
Here's an example that illustrates a TextBox that intercepts the WM_PASTE message.
And for reference, here's the definition of the message constants:
WM_PASTE
WM_COPY
WM_CUT
You'd simply ignore the inbound message, like so:
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_PASTE || m.Msg == WM_COPY || m.Msg == WM_CUT)
{
// ignore input if it was from a keyboard shortcut
// or a Menu command
}
else
{
// handle the windows message normally
base.WndProc(ref m);
}
}
Suppose you have a TextBox named textbox1. It sounds like you want to disable the cut, copy and paste functionality of a TextBox.
Try this quick and dirty proof of concept snippet:
private void Form1_Load(object sender, EventArgs e)
{
ContextMenu _blankContextMenu = new ContextMenu();
textBox1.ContextMenu = _blankContextMenu;
}
private const Keys CopyKeys = Keys.Control | Keys.C;
private const Keys PasteKeys = Keys.Control | Keys.V;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if ((keyData == CopyKeys) || (keyData == PasteKeys))
{
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
To prevent users to copy/paste using the keyboard set ShortcutsEnabled property to false.
To prevent users to copy/paste from the context menu set ContextMenu property to new ContextMenu().
if (copyPasteEnabled) {
textBox1.ShortcutsEnabled = true;
textBox1.ContextMenu = null;
} else {
textBox1.ShortcutsEnabled = false;
textBox1.ContextMenu = new ContextMenu();
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
}
if (e.Control == true)
{
switch (e.KeyCode)
{
case Keys.C:
case Keys.P:
case Keys.X:
e.Handled = true;
textBox1.SelectionLength = 0;
break;
}
}
}
private void textBox1_Enter(object sender, EventArgs e)
{
System.Windows.Forms.Clipboard.Clear();
}
int cusorposition = m_TextBox1.SelectionStart;
if (TextBox1.Text[0] == ' ')
{
//Trim Spaces at beginning.
m_TextBox1.Text = m_TextBox1.Text.TrimStart(' ');
m_TextBox1.Text = m_TextBox1.Text.TrimEnd(' ');
m_TextBox1.SelectionStart = cusorposition ;
}
Hi I found a way how to get the current cursor position instead of handling cut, copy and Paste event in a text box named TextBox1.Here in the above I am keeping the backup of current Cursor Position and after trimming the extra spaces from the starting and from end position I am reassigning the current cursor position.
Thanks to all who helped me to fix this problem.

How do I capture the enter key in a windows forms combobox

How do I capture the enter key in a windows forms combo box when the combobox is active?
I've tried to listen to KeyDown and KeyPress and I've created a subclass and overridden ProcessDialogKey, but nothing seems to work.
Any ideas?
/P
Hook up the KeyPress event to a method like this:
protected void myCombo_OnKeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
MessageBox.Show("Enter pressed", "Attention");
}
}
I've tested this in a WinForms application with VS2008 and it works.
If it isn't working for you, please post your code.
In case you define AcceptButton on your form, you cannot listen to Enter key in KeyDown/KeyUp/KeyPress.
In order to check for that, you need to override ProcessCmdKey on FORM:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if ((this.ActiveControl == myComboBox) && (keyData == Keys.Return)) {
MessageBox.Show("Combo Enter");
return true;
} else {
return base.ProcessCmdKey(ref msg, keyData);
}
}
In this example that would give you message box if you are on combo box and it works as before for all other controls.
or altertatively you can hook up the KeyDown event:
private void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("Enter pressed.");
}
}
private void comboBox1_KeyDown( object sender, EventArgs e )
{
if( e.KeyCode == Keys.Enter )
{
// Do something here...
} else Application.DoEvents();
}
Try this:
protected override bool ProcessCmdKey(ref Message msg, Keys k)
{
if (k == Keys.Enter || k == Keys.Return)
{
this.Text = null;
return true;
}
return base.ProcessCmdKey(ref msg, k);
}
It could be that your dialog has a button that's eating the enter key because it's set to be the AcceptButton in the form property.
If that's the case then you solve this like this by unsetting the AcceptButton property when the control gets focus then resetting it back once the control loses focus ( in my code, button1 is the accept button )
private void comboBox1_Enter(object sender, EventArgs e)
{
this.AcceptButton = null;
}
private void comboBox1_Leave(object sender, EventArgs e)
{
this.AcceptButton = button1;
}
private void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
MessageBox.Show("Hello");
}
}
I have to admit not liking my own solution as it seems a little hacky to unset/set the AcceptButton property so if anyone has a better solution then I'd be interested
protected void Form_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13) // or Key.Enter or Key.Return
{
MessageBox.Show("Enter pressed", "KeyPress Event");
}
}
Don't forget to set KeyPreview to true on the form.

Categories

Resources