Table of Contents
Creating Dynamic Menu from Data Source

EO.Wpf Menu derives from MenuBase, which in turn derives from ItemsControl, so you can uses the ItemsControl's ItemsSource property to populate the menu. This topic covers the following scenarios:

Populating from a string array

The following sample uses an array for ItemsSource:

//Populate the items from an array
Menu1.ItemsSource = new string[]{"_File", "_Edit", "_View", "_Window", "_Help"};

The above code produces the following result:

ItemsSource takes any objects that implements IEnumerable. The following code uses a List to achieve the same result:

//Build the item list
List<string> items = new List<string>();
items.Add("_File");
items.Add("_Edit");
items.Add("_View");
items.Add("_Window");
items.Add("_Help");

//Populate the menu from the item list
Menu1.ItemsSource = items;

Populating from a list of complex objects

The object in the list can be complex object. For example, the following sample demonstrates how to use the Celebrity object to populate the Menu:

Celebrity[] popularSingers = new Celebrity[]
{
    new Celebrity("Carly Rae Jepsen", "Carly_Rae_Jepsen.gif"),
    new Celebrity("Cher Lloyd", "Cher_Lloyd.gif"),
    new Celebrity("Chris Brown", "Chris_Brown.gif"),
    new Celebrity("Flo Rida", "Flo_Rida.gif"),
    new Celebrity("Justin Bieber", "Justin_Bieber.gif"),
    new Celebrity("Katy Perry", "Katy_Perry.gif"),
    new Celebrity("Kelly Clarkson", "Kelly_Clarkson.gif"),
};

Menu1.ItemsSource = popularSingers;

There are two ways to display the singer's name as menu item text: either through ItemContainerStyle or ItemTemplate. The following code demonstrates how to use ItemContainerStyle to display the Celebrity's Name property as menu item text:

XAML
<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:eo="http://schemas.essentialobjects.com/wpf/"
        Title="MainWindow" Height="250" Width="350">
    <StackPanel>
        <eo:Menu x:Name="Menu1" IsMainMenu="True">
            <eo:Menu.ItemContainerStyle>
                <Style TargetType="{x:Type eo:MenuItem}">
                    <Setter Property="Header" Value="{Binding Name}"></Setter>
                </Style>
            </eo:Menu.ItemContainerStyle>
        </eo:Menu>
    </StackPanel>
</Window>

The following code demonstrates how to achieve the same result with ItemTemplate:

XAML
<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:eo="http://schemas.essentialobjects.com/wpf/"
        Title="MainWindow" Height="250" Width="350">
    <StackPanel>
        <eo:Menu x:Name="Menu1" IsMainMenu="True">
            <eo:Menu.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"></TextBlock>
                </DataTemplate>
            </eo:Menu.ItemTemplate>
        </eo:Menu>
    </StackPanel>
</Window>

Populating multi-level menu from complex objects

Both ItemContainerStyle and ItemTemplate can be used to popular multi-level menu. The following code demonstrates how to use ItemTemplate to poulate multi-level menu:

Celebrity[] popularSingers = new Celebrity[]
{
    new Celebrity("Carly Rae Jepsen", "Carly_Rae_Jepsen.gif"),
    new Celebrity("Cher Lloyd", "Cher_Lloyd.gif"),
    new Celebrity("Chris Brown", "Chris_Brown.gif"),
    new Celebrity("Flo Rida", "Flo_Rida.gif"),
    new Celebrity("Justin Bieber", "Justin_Bieber.gif"),
    new Celebrity("Katy Perry", "Katy_Perry.gif"),
    new Celebrity("Kelly Clarkson", "Kelly_Clarkson.gif"),
};

Celebrity[] popularActors = new Celebrity[]
{
    new Celebrity("Cate Blanchett", "Cate_Blanchett.gif"),
    new Celebrity("Denzel Washington", "Denzel_Washington.gif"),
    new Celebrity("Julia Roberts", "Julia_Roberts.gif"),
    new Celebrity("Merly Streep", "Meryl_Streep.gif"),
    new Celebrity("Tom Cruise", "Tom_Cruise.gif"),
    new Celebrity("Tom Hanks", "Tom_Hanks.gif"),
};

CelebrityCategory[] categories = new CelebrityCategory[]
{
    new CelebrityCategory("Popular Signers", "music.png", popularSingers),
    new CelebrityCategory("Popular Actors", "movie.png", popularActors),
};

Menu1.ItemsSource = categories;

The key in the above sample is it also bind the MenuItem's ItemsSource to the CelebrityCategory object's Celebrities property. You can also achieve the same result by using a HierarchicalDataTemplate with ItemTemplate:

XAML
<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:eo="http://schemas.essentialobjects.com/wpf/"
        Title="MainWindow" Height="250" Width="350">
    <StackPanel>
        <eo:Menu x:Name="Menu1" IsMainMenu="True">
            <eo:Menu.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Path=Celebrities}">
                    <TextBlock Text="{Binding Name}"></TextBlock>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}"></TextBlock>
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </eo:Menu.ItemTemplate>
        </eo:Menu>
    </StackPanel>
</Window>