StrataFrame Forum

Maintenance Form Toolstrip & Shortcut Keys

http://forum.strataframe.net/Topic5917.aspx

By Chris Crabtree - 1/17/2007

First, I have a suggestion for a themed point release sometime in SF's future. Have one point release dedicated to finding all the opportunities for shortcut keys in all the designers. SF is a wonderfully fast development tool--and it would be faster still if I didn't have to take my hand off the keyboard to mouse around so much during design.

But that's not what I'm asking about here. Smile

In the Maintenance Form Toolstrip, I understand why you wouldn't necessarily set default shortcut keys for Edit, Save, Undo, etc. You don't want to conflict with other logic a developer may implement on a form.

However, it would be valuable to have a way to set the shortcut keys for toolstrip items. I tried editing the Items collection and changing the Text of the Edit button from 'Edit' to '&Edit'. To no avail. The designer resets all the default properties of all the built-in toolstrip buttons, it appears (as an aside, is that intentional?).

Now, I can add a new item and shortcut it just fine: I added another Edit item with the Text '&Edit' and it behaves as expected. So I could workaround the issue I guess, but I'd rather not have to wire up a bunch of fake toolstrip items to get this fairly standard behavior going.

Suggestions?

Thanks!

By StrataFrame Team - 1/18/2007

The removing of any changes that you set is not by design from us.  It's just the nature of the way design-time changes are "serialized" within the designer file of your form and the designer file of the MaintenanceFormToolstrip and the order in which your code and the MaintenanceFormToolstrip's code is executed within the InitializeComponent() method of your form. 

To ensure that your changes don't get overwritten, you can set the appropriate properties programmatically, after the InitializeComponent() method is executed.  So, you could set the edit button's text to &Edit within your constructor, you just have to do it after the InitializeComponent() method is executed.

By Chris Crabtree - 1/18/2007

Got it. That works, thanks!
By Chris Crabtree - 1/18/2007

Having a bunch of forms already using the MaintenanceFormToolStrip, I took things one step further to save time. I subclassed the MaintenanceFormToolStrip and simply performed the following steps:

  • Edit-->Find and Replace-->Replace in Files (Ctrl+Shift+H)
    • Find: MicroFour.StrataFrame.UI.Windows.Forms.MaintenanceFormToolStrip();
    • Replace With: SFHelper.MyMaintenanceFormToolStrip();
  • Edit-->Find and Replace-->Replace in Files (Ctrl+Shift+H)
    • Find: MicroFour.StrataFrame.UI.Windows.Forms.MaintenanceFormToolStrip
    • Replace With: SFHelper.MyMaintenanceFormToolStrip

Fixed up 14 forms in no time. Smile

And here is the code if anyone wants to take off on the idea. I made it generic for any particular set of buttons that are present. It will choose unique shortcut keys for each button automatically if possible, but the order of items does matter.

For example, if you had four buttons in this order: Newest Newer Newish New. It would assign shortcut keys 'N' for the first, 'e' for the second, 'w' for the third, and just give up on the fourth since all three of its letters were already in use. The button would still be there and everything, but just no shortcut key. This should be rare, I think.

using System;

using System.Collections.Generic;

using System.Text;

using MicroFour.StrataFrame.UI.Windows.Forms;

using System.Windows.Forms;

using System.Diagnostics;

namespace SFHelper

{

public class MyMaintenanceFormToolStrip: MaintenanceFormToolStrip

{

public MyMaintenanceFormToolStrip()

{

SetupToolStripShortcuts();

}

public void SetupToolStripShortcuts()

{

foreach (ToolStripItem item in this.Items)

{

ToolStripButton button = item as ToolStripButton;

if (button != null)

{

ApplyDisplayStyle(button);

ApplyShortcutKey(button);

}

}

}

protected void ApplyDisplayStyle(ToolStripButton button)

{

if (button.DisplayStyle == ToolStripItemDisplayStyle.Image)

{

button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;

}

else

{

if (button.DisplayStyle == ToolStripItemDisplayStyle.None)

{

button.DisplayStyle = ToolStripItemDisplayStyle.Text;

}

}

}

protected void ApplyShortcutKey(ToolStripButton button)

{

string text = button.Text;

if (text.Length <= 0)

{

text = StripCommandPrefix(button.Name);

}

Debug.Assert(text.Length > 0);

char shortcutKey = ChooseShortcutKey(text);

button.Text = InsertShortcut(text, shortcutKey);

}

protected string InsertShortcut(string text, char shortcutKey)

{

string result = text;

int position=text.IndexOf(shortcutKey);

if (position >= 0)

{

result=text.Insert(position, "&");

}

return result;

}

protected char ChooseShortcutKey(string s)

{

char result = char.MinValue;

string sLower = s.ToLower();

for (int i = 0; i < sLower.Length; i++)

{

char candidateLower = sLower[i];

char candidateOriginal = s[i];

if (IsCandidateInUse(candidateLower) == false)

{

_shortcutsInUse.Add(candidateLower);

result = candidateOriginal;

break;

}

}

return result;

}

protected bool IsCandidateInUse(char c)

{

return _shortcutsInUse.Contains(c);

}

protected string StripCommandPrefix(string s)

{

Debug.Assert(s.Length > 3);

Debug.Assert(s.StartsWith("cmd"));

return s.Remove(0, 3);

}

private List<char> _shortcutsInUse = new List<char>();

}

}

By StrataFrame Team - 1/19/2007

Yes, subclassing is certainly the best way to do it Smile  Promotes the best reuse.

Thanks for posting the code for others.

By Randy Jean - 1/23/2007

Yeah, I definitely can use this. Thanks! One of the requirements of the app I'm working on is that the users be able to navigate without the use of the mouse, if they so choose. (they are coming straight from the DOS world) Even though it may be a training issue on the Alt+ combinations at least we can say they don't have to use the mouse.