Center header in menu control - wpf

How do I vertically center a header in the menu control?
This was my try:
<MenuItem Header="File" StaysOpenOnClick="True" FontFamily="Arial" VerticalAlignment="Center">
<MenuItem Header="Open" Click="Open_Click" IsEnabled="True"/>
</MenuItem>
</Menu>
But its aligned to the Top-left.
What am I doing wrong?
[EDIT]
My whole menu now looks like this:
<Menu Canvas.Left="0" Canvas.Top="0" Name="menu1" Margin="0,0,0,384">
<MenuItem Header="File" StaysOpenOnClick="True" FontFamily="Arial" VerticalAlignment="Center">
<MenuItem Click="Open_Click" IsEnabled="True">
<MenuItem.Header>
<TextBlock Text="Open" VerticalAlignment="Center"/>
</MenuItem.Header>
</MenuItem>
</MenuItem>
</Menu>
The header text 'file' still isn't vertically centered (which is what i want to center).
What exactly is this code centering? Is it the text 'open'?
[/EDIT]

If you want to format the header you'll need to explicitly layout the header control:
<MenuItem StaysOpenOnClick="True" FontFamily="Arial" VerticalAlignment="Center">
<MenuItem Click="Open_Click" IsEnabled="True">
<MenuItem.Header>
<TextBlock Text="Open" VerticalAlignment="Center"/>
</MenuItem.Header>
</MenuItem>
</Menu>
Update:
To format the position of a MenuItem in the Menu you'll need to override the Menu's ItemsPanelTemplate. By default the Menu uses a vertical WrapPanel which justifies the items to the top. Replace the default with a panel of your choice (StackPanel, Grid, DockPanel, etc) and you'll be able center the menu items as you please. Here's an example:
<Menu Canvas.Left="0" Canvas.Top="0" Name="menu1" Margin="0,0,0,384">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="File" StaysOpenOnClick="True" FontFamily="Arial" VerticalAlignment="Center" >
<MenuItem Header="Open" Click="Open_Click" IsEnabled="True"/>
</MenuItem>
</Menu>
Information gathered from this post on MSDN.

I think you would want to set the VerticalContentAlignment. If the aligmnet is still not to your liking there is probably a problem with the default MenuItem Template, it may not bind to the property or there are some margins or Paddings which shift the header.

Related

xaml menu bottom and top alignment

I have a left-aligned vertical menu which stretches to my entire screen.
I want the first three options to end in the top left and the last two options to be in the bottom left.
Whatever I try I can't get the last two options to align to the bottom.
My current XAML is this:
<Menu HorizontalAlignment="Left">
<Menu.ItemsPanel>
<ItemsPanelTemplate >
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="Option A" VerticalAlignment="Top"/>
<MenuItem Header="Option B" VerticalAlignment="Top"/>
<MenuItem Header="Option C" VerticalAlignment="Top"/>
<MenuItem Header="Logout" VerticalAlignment="Bottom"/>
<MenuItem Header="Settings" VerticalAlignment="Bottom"/>
</Menu>
Current situation
Desired situation
Edit:
I'd prefer to not use rows if possible.
If you really do not want to use rows, consider using a DockPanel. Also note that the bottom-docked items are in reverse order.
<Menu HorizontalAlignment="Left">
<Menu.ItemsPanel>
<ItemsPanelTemplate >
<DockPanel VerticalAlignment="Stretch" LastChildFill="False"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="Option A" DockPanel.Dock="Top"/>
<MenuItem Header="Option B" DockPanel.Dock="Top"/>
<MenuItem Header="Option C" DockPanel.Dock="Top"/>
<MenuItem Header="Settings" DockPanel.Dock="Bottom"/>
<MenuItem Header="Logout" DockPanel.Dock="Bottom"/>
</Menu>

MenuItem with image as header ignores alignment

First of all, I know there are lot of questions about alignment in wpf, and I've read some of them, but none seems to work in this case...
What do I have
I've a menu, where the third MenuItem doesn't have a text but an image. To be exact, this one:
I want this element to be right aligned, so after looking at some examples and problem with alignment questions in SO, I'm using the following code:
<MenuItem HorizontalAlignment="Right" HorizontalContentAlignment="Right">
<MenuItem.Header>
<StackPanel>
<Image Source="Resources/Img/donarBoton.gif" UseLayoutRounding="False" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
Problem
As you can see, even whith the HorizontalAlignment set to right, it doesn't appear on the right side.
I've read about it and found that the Menu where it is, need to have the same property set to Stretch, what I've tried too with no success. I even tried it with the DockPanel where the menu is located (just to try, I'm not used to WPF yet), but it does nothing either.
I've tried to add a text element after my image element too, in order to see if the problem is the MenuItem or any other thing in my configuration, but it didn't move to the right side either.
What am I doing wrong?
There's the full DockPanel code:
<DockPanel x:Name="superiorDock" Height="25" LastChildFill="False" VerticalAlignment="Top" Width="307">
<Menu x:Name="superiorMenu" Width="307" Height="25" DockPanel.Dock="Top" HorizontalAlignment="Stretch" >
<MenuItem Header="{Binding XPath=#topMenu_1}">
<MenuItem Header="{Binding XPath=#topMenu_2}"/>
<MenuItem Header="{Binding XPath=#topMenu_3}"/>
<Separator/>
<MenuItem Header="{Binding XPath=#topMenu_4}"/>
<Separator/>
<MenuItem Header="{Binding XPath=#topMenu_5}"/>
</MenuItem>
<MenuItem Header="{Binding XPath=#topMenu_6}">
<MenuItem Header="{Binding XPath=#topMenu_7}"/>
<Separator/>
<MenuItem Header="{Binding XPath=#topMenu_8}"/>
</MenuItem>
<MenuItem HorizontalAlignment="Right" HorizontalContentAlignment="Right">
<MenuItem.Header>
<StackPanel>
<Image Source="Resources/Img/donarBoton.gif" UseLayoutRounding="False" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
</Menu>
</DockPanel>
Thanks in advance
Use this:
<DockPanel x:Name="superiorDock" Height="25" LastChildFill="False" VerticalAlignment="Top" Width="307">
<Menu x:Name="superiorMenu" Width="307" Height="25" DockPanel.Dock="Top" HorizontalAlignment="Stretch">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="{Binding XPath=#topMenu_1}">
<MenuItem Header="{Binding XPath=#topMenu_2}"/>
<MenuItem Header="{Binding XPath=#topMenu_3}"/>
<Separator/>
<MenuItem Header="{Binding XPath=#topMenu_4}"/>
<Separator/>
<MenuItem Header="{Binding XPath=#topMenu_5}"/>
</MenuItem>
<MenuItem Header="{Binding XPath=#topMenu_6}">
<MenuItem Header="{Binding XPath=#topMenu_7}"/>
<Separator/>
<MenuItem Header="{Binding XPath=#topMenu_8}"/>
</MenuItem>
<MenuItem HorizontalAlignment="Right">
<MenuItem.Header>
<StackPanel>
<Image Source="Resources/Img/donarBoton.gif" UseLayoutRounding="False" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
</Menu>
</DockPanel>
The default ItemsPanel of the Menu uses a WrapPanel. The panel defined in the ItemsPanel will be used as the container of the MenuItems.
WrapPanel doesn't respect the HorizontalAlignment property of its children. That's why we change the ItemsPanel to one that does support this: DockPanel.

XAML Centering menuitem

So I made a simple menu with a Width of 55 I try to make my title ("FILE") centered within the button itself while still being on the left of the window.
At the moment the basic code looks like that
<Menu Height="25" VerticalAlignment="Top" Width="800" Margin="0">
<MenuItem Header="File" Margin="0" Height="25" Width="55" HorizontalContentAlignment="Center">
<MenuItem Header="Login"/>
<MenuItem Header="New User"/>
...
</MenuItem> </Menu>
I've already tried playing around with a code like
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
To remove the grid but no sucess it's only the actual menu being centered and not the text "FILE" within the button.
Here's an example of what the "FILE" looks like at the moment and I try to make it centered within the blue area.
http://i.stack.imgur.com/KRXw2.png
(Cannot post the actual image I don't have enough rep.)
Thanks.
You an achieve this by setting the MenuItem's header template to be a TextBlock, with the TextBlock being the same width of the MenuItem itself. Also, you will need to add a Margin to compensate for the default MenuItem template.
<Menu Height="25" VerticalAlignment="Top" Width="800" Margin="0">
<MenuItem Margin="0" Height="25" Width="55" HorizontalContentAlignment="Center">
<MenuItem.Header>
<TextBlock Text="File" HorizontalAlignment="Stretch" Margin="-7" Width="55" TextAlignment="Center"/>
</MenuItem.Header>
<MenuItem Header="Login"/>
<MenuItem Header="New User"/>
</MenuItem>
</Menu>

How to float two items in a menu bar

I want to float my two menu items in menu bar, but it isn't working.
Here's my code:
<Menu Height="30" Background="#ccc" VerticalAlignment="Top" Grid.ColumnSpan="2" Grid.RowSpan="2">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="New game" Click="NewGame"></MenuItem>
<MenuItem Header="About" Click="AboutWindow" HorizontalAlignment="Right"></MenuItem>
<MenuItem Header="Exit" Click="CloseWindow" HorizontalAlignment="Right"></MenuItem>
</Menu>
And my menu looks like this:
So you need just to make some little changes to your XAML:
<Menu Height="30" Background="#ccc" VerticalAlignment="Top" Grid.ColumnSpan="2" Grid.RowSpan="2">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch" LastChildFill="False" />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="New game" Click="NewGame" DockPanel.Dock="Left" />
<MenuItem Header="Exit" Click="CloseWindow" DockPanel.Dock="Right" />
<MenuItem Header="About" Click="AboutWindow" DockPanel.Dock="Right" />
</Menu>
And this is the result:
I hope this can help you
Since you're using a DockPanel as Items Panel, use DockPanel.Dock instead of HorizontalAlignment
<Menu Height="30" Background="#ccc" VerticalAlignment="Top" Grid.ColumnSpan="2" Grid.RowSpan="2">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="New game" Click="NewGame"></MenuItem>
<MenuItem Header="About" Click="AboutWindow" DockPanel.Dock="Right"></MenuItem>
<MenuItem Header="Exit" Click="CloseWindow" DockPanel.Dock="Right"></MenuItem>
</Menu>
You were already halfway there :P HorizontalAlignment doesn't affect the DockPanel behavior, so all your menu items were being docked to the left by default. Your last menu item was shown in the right side just because its container was stretched to fill the remaining space, leaving the menu item space to effectively align itself to the right (in that case, HorizontalAlignment had an effect, but only in how the menu item aligned inside its container, not how it was layouted inside the DockPanel)
EDIT - You may have to change the order in which "About" and "Exit" are defined in XAML, since I don't remember correctly how the precedence worked.

How do I right-align the 'help' menu item in WPF?

I have the following (simplifed) section in my XAML file:
<Menu Width="Auto" Height="20" Background="#FFA9D1F4" DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Cut"/>
</MenuItem>
<MenuItem Header="Help">
<MenuItem Header="About"/>
</MenuItem>
</Menu>
and it results in:
+-------------------------------------------+
| File Edit Help |
+-------------------------------------------+
| |
What do I need to do if I want the Help menu item on the right-hand side:
+-------------------------------------------+
| File Edit Help |
+-------------------------------------------+
| |
Alng the same principle and this time you dont need the grid and therefore dont need to know the number of items. Assign all items to the left except the help :)
<Menu Height="20" Background="#FFA9D1F4">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="File">
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Cut"/>
</MenuItem>
<MenuItem Header="Help" HorizontalAlignment="Right">
<MenuItem Header="About"/>
</MenuItem>
</Menu>
Another possible answer, if you always know how many menu items there will be (and that makes this answer fragile), is to define the Menu.ItemsPanel as a grid, set the Menu to Stretch, set the Grid.ColumnDefinitions appropriately, set the MenuItems to the appropriate Grid.Column, and set the HorizontalAlignment of the last menu item as Right.
<Menu Height="20" Background="#FFA9D1F4" DockPanel.Dock="Top" HorizontalAlignment="Stretch">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="File" Grid.Column="0">
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="Edit" Grid.Column="1">
<MenuItem Header="Cut"/>
</MenuItem>
<MenuItem Header="Help" Grid.Column="2" HorizontalAlignment="Right">
<MenuItem Header="About"/>
</MenuItem>
</Menu>
Alteration to the original answer, since as it is (with HorizontalAlignment="Stretch") the Edit menu will stretch all the way across the menu bar to the Help menu.
Also incorporating Rokke's submenu alignment suggestion...
<Menu Height="20" Background="#FFA9D1F4">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="File">
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Cut"/>
</MenuItem>
<MenuItem Header="_Help" HorizontalAlignment="Right" FlowDirection="RightToLeft">
<MenuItem Header="About..." FlowDirection="LeftToRight"/>
</MenuItem>
</Menu>
<Menu DockPanel.Dock="Top">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="_File">
<MenuItem Click="Exit_Clicked" Header="E_xit" />
</MenuItem>
<MenuItem Header="_User">
<MenuItem Click="ChangePassword_Clicked" Header="_Change Password..." />
</MenuItem>
<!-- Right adjusted help menu with sub menu keeping inside the main window -->
<MenuItem Header="_Help" HorizontalAlignment="Right" FlowDirection="RightToLeft">
<MenuItem Click="About_Clicked" Header="_About..." FlowDirection="LeftToRight" />
</MenuItem>
</Menu>
Just a small addition to the original answer. Including the two flow directions make the sub menu stay inside the window.
I don't think there is an easy way. Menu keeps all Items on one side and even ignores HorizontalContentAlignment of the Menu or HorizontalAlignment of the MenuItem.
But you could do a workaround. The margin property works. So i think you could bind the margin of the Help MenuItem to the width of the Menu. But you would have to use a Converter to calculate the margin from the width.
I dont know if its good to do something like that. I wouldn't. But if you really want it, thats a way that should work.
There are one, perhaps two, potential drawbacks to using either a DockPanel or a Grid, instead of the default WrapPanel.
If the window is too small to show all the menu items on one line, they won't wrap to the next.
If the menuitems will be shared for use in a different context, such as in a ContextMenu, the last item will be right-aligned

Resources