Blogs

The One With

Silverlight Menu Control: Customizing Appearance

     

By default, the AgMenu Control has an Apple type look and feel. And even though it looks slick already, sometimes it is necessary to change the way it looks to fit your application’s general look and feel.

....

xmlns:dxm="clr-namespace:DevExpress.AgMenu;assembly=DevExpress.AgMenu.v8.2"

....

<dxm:AgMenu VerticalAlignment="Top">

<dxm:AgMenuItem Header="File">

                    <dxm:AgMenuItem Header="New">

                        <dxm:AgMenuItem Header="Project" />

                        <dxm:AgMenuItem Header="File" />

                    </dxm:AgMenuItem>

                    <dxm:AgMenuItem Header="Open" />

                    <dxm:AgMenuItem Header="Save" />

                    <dxm:AgMenuSeparator />

                    <dxm:AgMenuItem Header="Exit" />

      </dxm:AgMenuItem>

</dxm:AgMenu>

 

To style the AgMenu we’ll use its Style and SubMenuStyle properties.

<UserControl.Resources>

<Style TargetType="dxm:AgMenu" x:Key="AgMenu;Office;Blue">

</Style>

 

<Style TargetType="dxm:AgPopupMenu" x:Key="AgPopupMenu;Office;Blue">

</Style>

</UserControl.Resources>

<dxm:AgMenu

Style="{StaticResource AgMenu;Office;Blue}"

SubMenuStyle="{StaticResource AgPopupMenu;Office;Blue}">

....

</dxm:AgMenu>

 

Here we can change how the popup looks by replacing the default template:

<UserControl.Resources>

    <ControlTemplate TargetType="dxm:AgPopupMenu" x:Key="AgPopupMenuTemplate;Office;Blue">

        <Grid>

            <Border Margin="4,4,0,0" Background="#26000000" />

                  <Grid Margin="0,0,4,4">

                        <Border Background="#FF6593CF" />

                        <dxm:AgSubMenuDefaultStyleHelper Background="#FF6593CF" />

                        <Border Background="#FFF6F6F6" Margin="1,1,1,1">

                              <dxm:AgMenuScrollViewer x:Name="ItemsPresenterContainer"

ScrollButtonsClickMode="{TemplateBinding ScrollButtonsClickMode}"

Margin="0,0,0,1">

                                    <ItemsPresenter />

                              </dxm:AgMenuScrollViewer>

                        </Border>

                  </Grid>

</Grid>

</ControlTemplate>

<Style TargetType="dxm:AgPopupMenu" x:Key="AgPopupMenu;Office;Blue">

            <Setter Property="Template" Value="{StaticResource AgPopupMenuTemplate;Office;Blue}" />

</Style>

</UserControl.Resources>

Template Parts

First, we need to understand that the control templates for the menu items are not static. Meaning that different templates are used for different menu items: based on menu’s orientation, item’s type etc… To help with that, AgMenu uses a special collection AgMenuTemplateList to expose these different templates.

There are two:

TemplateCollection:

TemplateCollection is used for the main menu templates. This is where you define menu’s background color, borders etc… both for Vertical and Horizontal menus.

ItemContainerTemplates:

ItemContainerTemplates is where you define the templates for individual items and sub-items.

TemplateCollection

We’ll start off with the TemplateCollection by copying the default one from the generic.xaml into our resource section. (You can use the <UserControl.Resources> or <Application.Resources> for that)

<local:AgMenuTemplateList>

    <local:AgMenuTemplateListItem Key="Horizontal">

        <local:AgMenuTemplateListItem.Template>

            <ControlTemplate TargetType="local:AgMenu">

                <Border CornerRadius="5,5,5,5" Padding="1,1,1,1">

                    <Border.Background>

                        <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">

                            <GradientStop Color="#FF6E6E6E" />

                            <GradientStop Color="#FFC2C2C2" Offset="1" />

                        </LinearGradientBrush>

                    </Border.Background>

                    <Grid>

                        <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="Auto" />

                            <ColumnDefinition Width="*" />

                        </Grid.ColumnDefinitions>

                        <Border x:Name="ElementEmptyArea" CornerRadius="0,4,4,0" Grid.Column="1">

                            <Border.Background>

                                <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">

                                    <GradientStop Color="#FFDEDEDE" />

                                    <GradientStop Color="#FFF1F1F1" Offset="1" />

                                </LinearGradientBrush>

                            </Border.Background>

                        </Border>

                        <ItemsPresenter HorizontalAlignment="Left" />

                        <local:AgMenuDefaultStyleHelper />

                    </Grid>

                </Border>

            </ControlTemplate>

        </local:AgMenuTemplateListItem.Template>

    </local:AgMenuTemplateListItem>

    <local:AgMenuTemplateListItem Key="Vertical">

        <local:AgMenuTemplateListItem.Template>

            <ControlTemplate TargetType="local:AgMenu">

                <Border CornerRadius="5,5,5,5" Padding="1,1,1,1" Background="#FFA3A2A3">

                    <Grid>

                        <Grid.RowDefinitions>

                            <RowDefinition Height="Auto" />

                            <RowDefinition Height="*" />

                        </Grid.RowDefinitions>

                        <Border x:Name="ElementEmptyArea" CornerRadius="0,0,4,4" Grid.Row="1" Background="#FFEBEBEB" />

                        <ItemsPresenter VerticalAlignment="Top" />

                        <local:AgMenuDefaultStyleHelper />

                    </Grid>

                </Border>

            </ControlTemplate>

        </local:AgMenuTemplateListItem.Template>

    </local:AgMenuTemplateListItem>

</local:AgMenuTemplateList>

And customize it the way we want our menu to look. Note that there are two template items that the menu will be looking for in the TemplateCollection list, Horizontal and Vertical, so we’ll need to provide templates for both.

<dxm:AgMenuTemplateList x:Key="TemplateCollection;Office;Blue">

    <dxm:AgMenuTemplateListItem Key="Horizontal">

        <dxm:AgMenuTemplateListItem.Template>

            <ControlTemplate TargetType="dxm:AgMenu">

                <Grid>

                    <Border x:Name="ElementEmptyArea">

                        <Border.Background>

                            <SolidColorBrush Color="#FFBFDBFF"></SolidColorBrush>

                        </Border.Background>

                    </Border>

                    <ItemsPresenter HorizontalAlignment="Left" />

                    <dxm:AgMenuDefaultStyleHelper />

                </Grid>

            </ControlTemplate>

        </dxm:AgMenuTemplateListItem.Template>

    </dxm:AgMenuTemplateListItem>

    <dxm:AgMenuTemplateListItem Key="Vertical">

        <dxm:AgMenuTemplateListItem.Template>

            <ControlTemplate TargetType="dxm:AgMenu">

                <Grid>

                    <Border x:Name="ElementEmptyArea" Background="#FFBFDBFF" />

                    <ItemsPresenter VerticalAlignment="Top" />

                    <dxm:AgMenuDefaultStyleHelper />

                </Grid>

            </ControlTemplate>

        </dxm:AgMenuTemplateListItem.Template>

    </dxm:AgMenuTemplateListItem>

</dxm:AgMenuTemplateList>

....

<Style TargetType="dxm:AgMenu" x:Key="AgMenu;Office;Blue">

<Setter Property="TemplateCollection" Value="{StaticResource TemplateCollection;Office;Blue}" />

</Style>

Horizontal:

Vertical:

ItemContainerTemplates

There are several control templates that the AgMenu will be looking for in the ItemContainerTemplates collection.

·         AgMenuItem;Horizontal

·         AgMenuItem;Vertical

·         AgMenuItem;Vertical;PopupMenuItem

·         AgMenuItem;Vertical;PopupMenuSubItem

·         AgMenuSeparator;Vertical;PopupMenuItem

We can see which one is used for what item type by creating a simple (bare-bones) template collection:

<dxm:AgMenuTemplateList x:Key="ItemContainerTemplates;Debug">

        <dxm:AgMenuTemplateListItem Key="AgMenuItem;Horizontal">

            <dxm:AgMenuTemplateListItem.Template>

                <ControlTemplate TargetType="dxm:AgMenuItem">

                    <Grid x:Name="ElementRoot" Background="#FFBFDBFF">

                        <ContentControl Content="{TemplateBinding Header}"></ContentControl>

                    </Grid>

                </ControlTemplate>

            </dxm:AgMenuTemplateListItem.Template>

        </dxm:AgMenuTemplateListItem>

        <dxm:AgMenuTemplateListItem Key="AgMenuItem;Vertical">

            <dxm:AgMenuTemplateListItem.Template>

                <ControlTemplate TargetType="dxm:AgMenuItem">

                    <Grid x:Name="ElementRoot" Background="#FFBFDBFF">

                        <ContentControl Content="{TemplateBinding Header}"></ContentControl>

                    </Grid>

                </ControlTemplate>

            </dxm:AgMenuTemplateListItem.Template>

        </dxm:AgMenuTemplateListItem>

        <dxm:AgMenuTemplateListItem Key="AgMenuItem;Vertical;PopupMenuItem">

            <dxm:AgMenuTemplateListItem.Template>

                <ControlTemplate TargetType="dxm:AgMenuItem">

                    <Grid x:Name="ElementRoot" Background="#FFBFDBFF">

                        <ContentControl Content="{TemplateBinding Header}"></ContentControl>

                    </Grid>

                </ControlTemplate>

            </dxm:AgMenuTemplateListItem.Template>

        </dxm:AgMenuTemplateListItem>

        <dxm:AgMenuTemplateListItem Key="AgMenuItem;Vertical;PopupMenuSubItem">

            <dxm:AgMenuTemplateListItem.Template>

                <ControlTemplate TargetType="dxm:AgMenuItem">

                    <Grid x:Name="ElementRoot" Background="#FFBFDBFF">

                        <ContentControl Content="{TemplateBinding Header}"></ContentControl>

                    </Grid>

                </ControlTemplate>

            </dxm:AgMenuTemplateListItem.Template>

        </dxm:AgMenuTemplateListItem>

        <dxm:AgMenuTemplateListItem Key="AgMenuSeparator;Vertical;PopupMenuItem">

            <dxm:AgMenuTemplateListItem.Template>

                <ControlTemplate TargetType="dxm:AgMenuSeparator">

                    <Grid x:Name="ElementRoot" Background="#FFBFDBFF">

                        <Border Height="1" Background="#FF9AC6FF" />

                    </Grid>

                </ControlTemplate>

            </dxm:AgMenuTemplateListItem.Template>

        </dxm:AgMenuTemplateListItem>

</dxm:AgMenuTemplateList>

....

<Style TargetType="dxm:AgMenu" x:Key="AgMenu;Office;Blue">

<Setter Property="TemplateCollection" Value="{StaticResource TemplateCollection;Office;Blue}" />

      <Setter Property="ItemContainerTemplates" Value="{StaticResource ItemContainerTemplates;Debug}" />           

</Style>

<Style TargetType="dxm:AgPopupMenu" x:Key="AgPopupMenu;Office;Blue">

<Setter Property="Template" Value="{StaticResource AgPopupMenuTemplate;Office;Blue}" />

<Setter Property="ItemContainerTemplates" Value="{StaticResource ItemContainerTemplates;Debug}" />

</Style>

And that’ it J

Below, you can download a complete set of templates to make your menus look like Office 2007.

Download

Cheers

Azret

Published Nov 10 2008, 05:02 PM by Azret Botash (DevExpress)
Filed under: ,
Technorati tags: Silverlight, AgMenu
Bookmark and Share

Comments

 

Silverlight News for November 11, 2008 said:

Pingback from  Silverlight News for November 11, 2008

November 11, 2008 2:53 AM
 

Community Blogs said:

In this issue: Matthew Casperson, Mehdi Slaoui Andaloussi, Tim Heuer, Dan Wahlin, Dave Britton, Jordan

November 11, 2008 10:54 PM
 

2008 November 12 - Links for today « My (almost) Daily Links said:

Pingback from  2008 November 12 - Links for today « My (almost) Daily Links

November 12, 2008 4:29 AM
 

Silverlight Travel said:

Nice Menues. Thanks for the Explanation

November 16, 2008 11:10 AM
 

Amit Chaudhary said:

How we can add an image left to File Text.

Means aading an image to the root item.

December 9, 2008 1:42 AM
 

Azret Botash (DevExpress) said:

Hello Amit,

You can add an image to the left of the MenuItem by simply assigning the AgMenuItem.Icon.

<dxm:AgMenuItem Header="File">

    <dxm:AgMenuItem.Icon>

              <Image Source="ButtonNew.png" />

    </dxm:AgMenuItem.Icon>

</dxm:AgMenuItem>

The office template that is attached to this project should support the AgMenuItem.icon.

Thanks

Azret

December 9, 2008 2:42 PM
 

Alex said:

great explanations!

i would like to use the default menu style, and only change one thing:

the horizontal main menu should be aligned to the

right, with the empty area on the left (similar to the

style in this blog), where i want to add some text.

i could achieve this by either moving the empty area column of the content template to the left, or by setting the borders of the menu items to zero and putting the menu into a parent border (stretch) with same background and borderbrush as the default menu style. this way i would also be free to add further text on the to the left of the menu.

1) is it possible to make such small changes in the XAML directly (AgMenu tag) without having to copy the entire

default template into a static resource? (e.g. switching the empty content to the left of the menu)

2) is it possible to get rid of the menuitem borders at runtime, when the adding the menuitems?

3) where would i find the borderbrush settings of the default template, so i could simulate the menu with a separate border?

would highly appreciate some help here!

thanks alex

February 5, 2009 3:48 PM
 

The One With said:

In my previous post I have explained how to customize the appearance of the AgMenu Control . The template

August 3, 2009 7:51 PM
More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.