C# WinForms ToolStripTextBox sizing and detect key press

305 views Asked by At

I have a very simple C# WinForm sample:

private System.Windows.Forms.ContextMenuStrip ct1;

var header = new ToolStripMenuItem("Header with long test like Lorem Ipsum");
header.Enabled = false;

var txt = new ToolStripTextBox();
txt.Text = "changeme";

ct1.Items.Clear();
ct1.Items.Add(header);
ct1.Items.Add(txt);

ct1.Show(x,y);

Now I have two issues with this:

  1. How can I ask the textbox to fill the full width of the menu (i.e. be as large as the largest item)? enter image description here

  2. If I press the Alt key, the menu closes. I can prevent it by handling the Closing event:

Like this:

private void ct1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    e.Cancel = (e.CloseReason == ToolStripDropDownCloseReason.Keyboard);
}

However I want to be able to close by pressing Escape, and I also want to be able to use Alt key as input.

But now Alt and Escape are all or nothing. How can I differentiate between them?

Tried even on KeyDown event for the TextBox and also for ct1, but Alt key is not forwarded to there.

1

There are 1 answers

10
Oguz Ozgul On BEST ANSWER

For your first question,

While it may require some tweaking, this will allow you to set the width of the text box to a good degree:

First, give your textbox a name and attach to these event handlers. This is required because the width of the context menu is not determined until it is shown.

txt.Name = "changeNameTextBox";
ct1.Opening += ct1_Opening;
ct1.Closed += ct1_Closed;

Then implement those event handlers:

void ct1_Opening(object sender, EventArgs e)
{
    ToolStripTextBox txt = ct1.Items.Find("changeNameTextBox", false)[0] as ToolStripTextBox;
    txt.Size = new Size(ct1.Width - 50, txt.Height);
}

void ct1_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
    ToolStripTextBox txt = ct1.Items.Find("changeNameTextBox", false)[0] as ToolStripTextBox;
    txt.Size = new Size(0, 25);
}

As for your second question, you almost made it.

Have that onClosing event, and modify its body like this:

void ct1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    e.Cancel =
        e.CloseReason == ToolStripDropDownCloseReason.Keyboard
        && 
        Control.ModifierKeys.HasFlag(Keys.Alt); 
}

Hope this helps.