Shortcuts Ctrl+C Ctrl+V dont work in Textboxes if MenuStrip has this Shortcuts set
Asked Answered
D

5

15

Goal: A Menustrip with Copy and Paste and the user shall see the Shortcut-Keys.

MenuStrip blocks TextBoxes

Problem: If you have a MenuStrip and set the ShortcutKeys the are "catched" by the Menu but no longer by the Textboxes. This means you cannot use Ctrl+C / V in the Textboxes - only by Right-Click. If you remove the Shortcuts the Textboxes work fine.

Why is that? Whats the solution if I dont want to name the Entry "Copy______Ctrl+C"?

Example Project: http://www.file-upload.net/download-4098087/MenuBlocksSTRG.zip.html

MSDN is down ATM i found this links:

Daune answered 8/2, 2012 at 14:9 Comment(6)
Normally you'd bind code that executes copy/paste to these menu items.Hesione
@JoeWhite Your link is about WPF, the question is about WinForms.Hesione
I think this question is related: #5114222Interinsurance
@CodeInChaos Whoops, you're right, I didn't read the bit about MenuStrip carefully enough.Unaccomplished
Better yet: myMenuItem.Text = "&Copy\tCtrl+C";Diluvium
"&Copy\tCtrl+C" does not work. Menu Entry is shown as "CopyCtrl+C". Spaces work but not 100% because the other Shortcuts Texts start some pixels to the right.Daune
U
2

This should work for copy, and you can take care of paste in same way:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.Control | Keys.C) && textBox1.ContainsFocus)
        {
            Clipboard.SetText(textBox1.SelectedText);
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
Umbrage answered 9/2, 2012 at 20:41 Comment(6)
Building the Clipboard is cumbersome. What if the Cursor starts not at the beginning of the textbox but in the middle of the text. What if some text is selected to copy or to replace. I choose to set the Menu Text to "Copy Ctrl+C"Daune
This works for copy in all cases (including the one you said), it takes selected text from textbox into clipboard. Did you try it? If you can't make paste according to this idea, report, so I'll write some code. And if you think that it is cumbersome, you asked to work around the way .net works. That is cumbersome.Schulte
Excellent solution. Though I changed the check to a more general this.ActiveControl is TextBox, since the rest of my program is an image editor :)Clavus
This can be done much simpler. I posted a complete new answer below. You don't need to handle the clipboard yourself. Just return false if the focus is on the textbox, and the textbox will handle it.Impassable
@EmilAlbert, I do different things now so I am not into testing your solution (and I haven't downvoted it), but if you call removing of one line as "much" simpler, that is not a proper wording and communication.Schulte
@Ivan Ičin Ok yes in your case it does not make much difference. I had the same issue with a much more complex ui. It has one editor window, where the copy/paste applies, and many text boxes and numeric controls for user input. For the complex ui it is much more simple if you can just return false, instead of handling every input field yourselfImpassable
B
2

If it still matters, the simple solution might be: Show only the shortcut keys text, as in the image.

Ctrl + V

In the TextBox set ShortcutsEnabled to true. That's all!

Briefs answered 19/3, 2017 at 1:47 Comment(0)
I
1

You probably have to handle things yourself in those cases.

Simple example:

private void copyToolStripMenuItem_Click(object sender, EventArgs e) {
  if (this.ActiveControl is TextBox) {
    Clipboard.SetText(((TextBox)this.ActiveControl).SelectedText);
  } else {
    // do your menu Edit-Copy code here
  }
}

private void pasteToolStripMenuItem_Click(object sender, EventArgs e) {
  if (this.ActiveControl is TextBox) {
    ((TextBox)this.ActiveControl).SelectedText = Clipboard.GetText();
  } else {
    // do you menu Edit-Paste code here
  }
}
Ivory answered 9/2, 2012 at 19:14 Comment(4)
Building the Clipboard is cumbersome. What if the Cursor starts not at the beginning of the textbox but in the middle of the text. What if some text is selected to copy or to replace. I choose to set the Menu Text to "Copy Ctrl+C"Daune
did you even try to apply code from answer, or you just said it is cumbersome? because, you would realize that this is not answer for you, it requires that when your menu is clicked, it handles copy or paste from your textbox, which is not what your menu should work.Schulte
@Daune Not sure what you mean. The posted example does the work for you. The SelectedText property is returning what is currently highlighted in the text box. The "else" part of the code is to handle copy-paste functions for non-textbox controls. If the menu functions are only for the textbox controls, then you won't have to worry about the "else" part.Ivory
It would make the menus unintuitive, though, since people would expect those menus to handle the global copy-paste of whatever it is the program normally handles, not the one in the textbox.Clavus
A
0

You need something like this?

ToolStripMenuItem Quit = new ToolStripMenuItem();
        Quit.Name = "quitToolStripMenuItem";
        Quit.Text = "&Quit";
        Quit.ShortcutKeys = Keys.Alt | Keys.F4;
        Quit.Click += new EventHandler(quitToolStripMenuItem_Click);
Atkins answered 7/1, 2014 at 18:3 Comment(0)
I
0

Ivan Ičin's solution would become difficult for more complex UIs. But it can be done simpler. Just return false if the focus is on the textbox:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == (Keys.Control | Keys.C) && textBox1.ContainsFocus) return false;
    return base.ProcessCmdKey(ref msg, keyData);
}

Also, the copy and paste points in the menubar normally refer to certain controls, let's call it editorControl. So I would rather inverse the test. This way other textboxes can be added to the form without the need to update this function.

With returning false it is also easy to handle Ctrl X and Ctrl V. So in the end I am using this:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (!_editorControl.ContainsFocus && (keyData is (Keys.Control | Keys.C) or (Keys.Control | Keys.V) or (Keys.Control | Keys.X))
    {
        return false;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}
Impassable answered 25/3 at 12:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.