How do I right align the shortcut keys in Menu? - winforms

I add my menu items shortcut keys, but they are poorly arranged.
and I need to make it like this:

Ah, I think I finally figured out how to do this (it had been puzzling me for quite some time how you'd gotten the two different screenshots...). It turns out there are two ways that you can instruct Windows to align shortcut keys in a drop-down menu.
The first (and probably most standard) way is to insert a tab character (\t) in the string corresponding to the menu text. This produces the bottom example shown in your original question, the one where all the identifiers are left-aligned and some overhang slightly. This is the standard in almost all Microsoft applications, and the only option that I knew existed until a few minutes ago.
Sample resource string: &Print…\tCtrl+P
The second way is to replace that \t escape sequence with \a in the resource string (which, yes, strangely enough would normally indicate an alert bell). This causes Windows to right align all of the shortcut key sequences in the menu, producing the example illustrated in your first screenshot. This does produce a menu that uses screen space more efficiently (it's smaller), but this comes at the cost of a neat alignment of each of the shortcut key sequences down their left-hand margins, which I think makes for slightly easier readability.
Sample resource string: &Print…\aCtrl+P
So if you want your menus to look like the second example in your original question (Yes, I've confusingly arranged my samples backwards. Sorry), you need to delimit the shortcut key sequence with a tab character (\t) in the resource file containing your menu item text strings.
The strange thing is that you claim to be using .NET WinForms, which handles all of this automatically (saving you from the pain of messing with resource files). I know for a fact that it inserts tab characters, and all of the menus I've ever seen it generate do look like your second example.
The best thing to do is switch your menu to the old MainMenu control included with earlier version of the .NET Framework. (To do this, you'll probably have to right-click on the Toolbox and add the control manually—it isn't there by default on later versions of Visual Studio.) This will ensure that you see the alignment behavior you expect, consistent with all of the standard Windows applications like Notepad. It also produces menus that look like the native operating system menus (in Vista and 7, they are painted blue) rather than the amateur-looking owner-drawn menus produced by the MenuStrip control that are completely out-of-place in modern versions of Windows.
Microsoft's official documentation does confirm that the MainMenu control is still supported for future use, so there's no reason to fear using it in your apps. I highly recommend everyone use this instead:
Although MenuStrip replaces and adds functionality to the MainMenu control of previous versions, MainMenu is retained for both backward compatibility and future use if you choose.

They are 'right' aligned, as you can see. (No pun intended).
This is default behaviour for a menu. You'll need custom drawing to do it differently.

Every OS has it's particular look and feel, and I guess that you have to have pretty good reasons not to honor how every other application on the windows looks. I guess you will either drop the issue, or will extend the menu with OwnerDrawn items.
Here is the overkill article on the subject.

Related

Converting multiple (and different) windows into tabs

Fairly new to WPF.
I'm tasked with converting our application with about ten different windows into a single-window, multi-tabbed application. I'd like your input on the most effective way of doing this.
I suppose I could do this the most-straightforward way -- copying and pasting a ton of code into the main XAML file. I imagine I'd end up with a gigantic file though, and would like to avoid that.
I should mention that the contents of each tab will be substantially different from each other.
There must be some element of WPF that enables this that I just haven't been able to find. Really appreciate any input.
In XAML there are user controls which you can use. That way, you could use one user-control per tab-content and let the main window only contain the tabview and tabitems and some minor logic code.
To achieve that, you can simply copy-paste most of your current window-code in one user control per window. The code base could remain almost the same (if there are no interactions between the windows at least).
There are quite many resources out there containing further details on user controls like this code-project article (a bit old, but the majority of its contents will still apply) or that MSDN one.

ToolStrip with ToolStripDropDownButton inside looks weird

I have two versions of a Windows Forms Application and can't figure for the life of me how to get a particular GUI behavior to be the same without copying the entire code (which is an obvious no-no).
Here is a visual comparison:
The left one is the one I want to fix so that it looks like the right one. Notice how the ToolStrip looks as if it contained an extra ToolStripDropDownButton, or some property or style I don't know about was set to make it look like that.
I've been diff'ing like crazy and couldn't find what differs. Any ideas?
Got it. In the left side case, the button was "overflowing". Its size was too large to fit the toolstrip and thus it was collapsed like that. After adjusting the button's size in the left side, all was good.
I found out what was going on after reading basic stuff about toolstrip controls here, in the "Using the CanOverflow and Overflow Properties" section.

MFC: how to render an Aero-style combo box for owner draw?

I have inherited a large MFC application which contains a CComboBox subclass that overrides OnPaint. Currently it does all its drawing by hand (with lines and rectangles), and renders a combo box that looks decidedly Windows 98-style. However, it otherwise works great and provides a lot of useful custom functionality that we rely on, and rewriting the entire control is probably not an option.
I would like to modernize it so that the OnPaint draws in Aero style where available (falling back to the old code when modern theming is unavailable). I've done this with some other custom controls we have, like buttons, and it works great for our purposes. I know there are some tiny behaviors that it won't get right, like gentle highlights on mouse-hover, but that's not a big deal for this app.
I have access to the CVisualStylesXP ckass, so I've already got the infrastructure to make calls like OpenThemeData, GetThemeColor or DrawThemeBackground pretty easily (via LoadLibrary so we don't force Vista as a min-system). Unfortunately, I don't know the proper sequence of calls to get a nice looking combo box with the theme-appropriate border and drop-down button.
Anyone know what to do here?
Honestly, I don't know why they originally tried to override OnPaint. Is there a good reason? I'm thinking that at least 99% of the time you are just going to want to override the drawing of the items in the ComboBox. For that, you can override DrawItem, MeasureItem, and CompareItem in a derived combo box to get the functionality you want. In that case, the OS will draw the non-user content specific to each OS correctly.
I think you best shot without diving in the depth of xp theming and various system metrics is take a look at this project: http://www.codeproject.com/Articles/2584/AdvComboBox-Version-2-1
Check the OnPaint of the CAdvComboBox class - there is a full implementation of the control repainting including xp theme related issues.
Not sure if it's the same situation - but when I faced this problem (in my case with subclassed CButtons), solving it only required changing the control declaration to a pointer and creating the control dynamically.
Let's assume that your subclassed control is called CComboBoxExt.
Where you had
CComboBoxExt m_cComboBoxExt;
You'll now have
CComboBoxExt* m_pcComboBoxExt;
And on the OnInitDialog of the window where the control is placed, you create it using
m_pcComboBoxExt = new CComboBoxExt();
m_pcComboBoxExt->Create(...)
Since this is now a pointer, don't forget to call DestroyWindow() and delete the pointer on termination.
This solved my particular problem - if your control is declared in the same way, consider giving it a try.

WPF: What do you call dual windows where you select from one into the other?

OK this is a somewhat strange question but I've seen this often so I'm assuming it has a name and maybe some tutorials on how to do it.
Imagine two listboxes side by side with the first one full of items. You can select some items from the first press a button between them (often a arrow pointing towards the empty one) to select into the other. This usually is used when you are selecting a smaller SET from a larger one.
This is something you see on a regular basis and made me think it's supported in WPF in wome way.
I'm sure I could create it from scratch but don't wan't to bother if it's already available.
Anyone have any idea?
I'm not sure if this has a formal name, but I don't think it's supported in WPF as a native control, nor with the official Microsoft WPF Toolkit (which does have some interesting add-on controls, by the way). It wouldn't be too hard to build one with 2 ListBoxes and some buttons, as you say.
In our shop, we have a reusable (WinForms) control for this, and we call it a "double list". It's not a great name, but at least we know what it means.

WPF UI element naming conventions

Although Hungarian notation is considered bad practice nowadays, it is still quite common to encode the type in the name of user interface elements, either by using a prefix (lblTitle, txtFirstName, ...) or a suffix (TitleLabel, FirstNameTextBox, ...).
In my company, we also do this, since it makes code written by co-workers (or by yourself a long time ago) easier to read (in my experience). The argument usually raised against doing this -- you have to change the name of the variable if the type changes -- is not very strong, since changing the type of a UI element usually requires rewriting all parts of the code were it is referenced anyway.
So, I'm thinking about keeping this practice when starting with WPF development (hmmm... should we use the txt prefix for TextBlocks or TextBoxes?). Is there any big disadvantage that I have missed? This is your chance to say "Don't do this, because ...".
EDIT: I know that with databinding the need to name UI elements decreases. Nevertheless, it's necessary sometimes, e.g. when developing custom controls...
Personally, I find that WPF changes the rules when it comes to this. Often, you can get away with little or no code behind, so having the prefixes to distinguish names makes things more confusing instead of less confusing.
In Windows Forms, every control was referenced by name in code. With a large UI, the semi-hungarian notation was useful - it was easier to distinguish what you were working with.
In WPF, though, it's a rare control that needs a name. When you do have to access a control via code, it's often best to use attached properties or behaviors to do so, in which case you're never dealing with more than a single control. If you're working in the UserControl or Window code-behind, I'd just use "Title" and "Name" instead of "txtTitle", especially since now you'll probably only be dealing with a few, limited controls, instead of all of them.
Even custom controls shouldn't need names, in most cases. You'll want templated names following convention (ie: PART_Name), but not actual x:Name elements for your UIs...
In my experience - In WPF when you change the type of a control, you normally do not have to rewrite any code unless you did something wrong. In fact, most of the time you do not reference the controls in code. Yes, you end up doing it, but the majority of references to a UI element in WPF is by other elements in the same XAML.
And personally, I find "lblTitle, lblCompany, txtFirstName" harder to read than "Title". I don't have .intWidth and .intHeight (goodbye lpzstrName!). Why have .lblFirstName? I can understand TitleField or TitleInput or whatever a lot more as it's descriptive of the what, not the how.
For me, wishing to have that type of separation normally means my UI code is trying to do too much - of course it's dealing with a UI element, it's in the window code! If I'm not dealing with code around a UI element, why in the world would I be coding it here?
Even from a Winforms perspective I dislike semi-hungarian.
The biggest disadvantage in my opinion, and I've written a LOT of ui code is that hungarian makes bugs harder to spot. The compiler will generally pick it up if you try to change the checked property on a textbox, but it won't pick up something like:
lblSomeThing.Visible = someControlsVisible;
txtWhatThing.Visible = someControlsVisible;
pbSomeThing.Visible = someControlsVisible;
I find it MUCH easier to debug:
someThingLabel.Visible = someControlsVisible;
whatThingTextBox.Visible = someControlsVisible;
someThingPictureBox.Visible = someControlsVisible;
I also think it's far better to group an addCommentsButton with an addCommentsTextBox than to group a btnAddComments with a btnCloseWindow. When are you ever going to use the last two together?
As far as finding the control I want, I agree with Philip Rieck. I often want to deal with all the controls that relate to a particular logical concept (like title, or add comments). I pretty much never want to find just any or all text boxes that happens to be on this control.
It's possibly irrelevant in WPF, but I think hungarian should be avoided at all times.
I like using a convention (just a good idea in general), but for UI stuff I like it to have the type of the control at the front, followed by the descriptive name -- LabelSummary, TextSummary, CheckboxIsValid, etc.
It sounds minor, but the main reason for putting the type first is that they'll appear together in the Intellisense list -- all the labels together, checkboxes, and so on.
Agree with the other answers that it's mainly personal preference, and most important is just to be consistent.
On the need for naming at all, given the prevalence of data binding... one thing you might want to consider is if your UI is ever subjected to automated testing. Something like QTP finds the visual elements in an application by Name, and so an automation engineer writing test scripts will greatly appreciate when things like tabs, buttons etc. (any interactive control) are all well named.
In WPF you practically never need (or even want) to name your controls. So if you're using WPF best practices it won't matter what you would name your controls if you had a reason to name them.
On those rare occasions where you actually do want to give a control a name (for example for an ElementName= or TargetName= reference), I prefer to pick a name describing based on the purpose for the name, for example:
<Border x:Name="hilightArea" ...>
...
<DataTrigger>
...
<Setter TargetName="hilightArea" ...
I prefix any user-interface name with two underscores, as in __ so it is sorted before other properties when debugging. When I need to use IntelliSense to find a control, I just type __ and a list of controls displays. This continues the naming convention of prefixing a single underscore to module level variables, as in int _id;.
You can use the official Microsoft website for Visual Basic 6 control naming conventions, and perhaps combine it with the recommended C# naming conventions. It's very specific, is widely used by developers in C# as well for control names, and can still be used in a WPF or Windows Forms context.
Visual Basic 6 control naming conventions: Object Naming Conventions
C# recommended naming conventions in general: General Naming Conventions

Resources