Blogs

The One With

November 2008 - Posts

  • 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

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.