Intersoft ClientUI Documentation
UXMenuBar

UXMenuBar is a full-featured menu bar control with access key, command support and customizable style. It supports a variety of menu item types with full customization and binding support.

You can also customize the access key visibility along with other user experience aspects such as opening sub menu on mouse over, hide menu on menu item click / stack on menu item click and more.

Selection Control

UXMenuBar is inherited from ISSelectionControl which means it contains properties to indicate and control the current selection such as SelectedIndex, SelectedItem, SelectedValue, SelectedValuePath, SelectedElement which you can bind to a DataContext using object binding, or using MVVM pattern. To learn more about MVVM pattern, see MVVM Pattern Overview.

Any changes to one of the properties means that the current selection has changed, and it will synchronize the UI and other related properties automatically. To learn more about selection control see Items Control Overview.

Data Binding

UXMenuBar supports data binding / hierarchical binding. To learn more about data binding, see Data Binding Overview.

To bind the data you can either use ItemTemplate or the member path properties such as:

The following example shows how to perform hierarchical binding to UXMenuBar.

Model
Copy Code
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace ClientUI.Samples.Models
{
    public class ItemObject : INotifyPropertyChanged
    {
        private string _text;
        private ObservableCollection<ItemObject> _subItems;

        public string Text
        {
            get { return this._text; }
            set
            {
                if (this._text != value)
                {
                    this._text = value;
                    this.OnPropertyChanged("Text");
                }
            }
        }

        public ObservableCollection<ItemObject> SubItems
        {
            get { return this._subItems; }
            set
            {
                if (this._subItems != value)
                {
                    this._subItems = value;
                    this.OnPropertyChanged("SubItems");
                }
            }
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
View Model
Copy Code
using System.Collections.ObjectModel;
using System.ComponentModel;
using ClientUI.Samples.Models;

namespace ClientUI.Samples.ViewModels
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        public MainPageViewModel()
        {
            this.Items = new ObservableCollection<ItemObject>();

            ItemObject newItem = new ItemObject() { Text = "New" };
            newItem.SubItems = new ObservableCollection<ItemObject>();
            newItem.SubItems.Add(new ItemObject() { Text = "File" });
            newItem.SubItems.Add(new ItemObject() { Text = "Save" });
            newItem.SubItems.Add(new ItemObject() { Text = "Exit" });

            ItemObject help = new ItemObject() { Text = "Help" };
            help.SubItems = new ObservableCollection<ItemObject>();
            help.SubItems.Add(new ItemObject() { Text = "About" });

            this.Items.Add(newItem);
            this.Items.Add(help);
            
        }

        private ObservableCollection<ItemObject> _items;

        public ObservableCollection<ItemObject> Items
        {
            get { return this._items; }
            set
            {
                if (this._items != value)
                {
                    this._items = value;
                    this.OnPropertyChanged("Items");
                }
            }
        }

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
View
Copy Code
<UserControl x:Class="ClientUI.Samples.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Intersoft="http://intersoft.clientui.com/schemas"    
    xmlns:vm="clr-namespace:ClientUI.Samples.ViewModels"
    mc:Ignorable="d"
    d:DesignHeight="400" d:DesignWidth="800">
        <UserControl.Resources>
        
                <Style x:Key="MenuBarItemStyle" TargetType="Intersoft:UXMenuItem">
                        <Setter Property="DisplayMemberPath" Value="Text"/>
                        <Setter Property="PreferredPosition" Value="BottomLeft"/>
                        
                            ...
            
                        <Setter Property="Template">
                                <Setter.Value>
                                        <ControlTemplate TargetType="Intersoft:UXMenuItem">
                                                <Grid x:Name="RootElement" Background="{TemplateBinding Background}">
                                                        
                                                        ...
                            
                                                </Grid>
                                        </ControlTemplate>
                                </Setter.Value>
                        </Setter>
                </Style>
                <Style x:Key="UXMenuBarStyle1" TargetType="Intersoft:UXMenuBar">
                        
                           ...
            
                        <Setter Property="ItemContainerStyleSelector">
                                <Setter.Value>
                                        <Intersoft:UXMenuBarStyleSelector MenuBarItemStyle="{StaticResource MenuBarItemStyle}">
                                                <Intersoft:ContainerStyle Style="{StaticResource MenuVertical_Separator}" TypeName="UXSeparator"/>
                                        </Intersoft:UXMenuBarStyleSelector>
                                </Setter.Value>
                        </Setter>
                        
                           ...
            
                </Style>
        </UserControl.Resources>
        
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.DataContext>
            <vm:MainPageViewModel/>
        </Grid.DataContext>
        <Intersoft:UXMenuBar VerticalAlignment="Top" HorizontalAlignment="Left" Width="150" 
                             ItemsSource="{Binding Items}" DisplayMemberPath="Text" CollectionMemberPath="SubItems" Style="{StaticResource UXMenuBarStyle1}">           

        </Intersoft:UXMenuBar>
    </Grid>


</UserControl>

This example is using MVVM pattern that utilize the binding concept. To learn more about MVVM pattern, see MVVM Pattern Overview.

Understanding UXMenuItem

The item container type of UXMenuBar is UXMenuItem.

UXMenuItem implements both ICommandSource and INavigationSource to support commanding and navigation, which is shown in the following example. 

XAML
Copy Code
<Intersoft:UXMenuBar VerticalAlignment="Top" HorizontalAlignment="Left" Width="150">
    <Intersoft:UXMenuItem Header="File">
        <Intersoft:UXMenuItem Header="New" Command="{Binding NewCommand}"/>
        <Intersoft:UXMenuItem Header="Save" Command="{Binding SaveCommand}"/>
        <Intersoft:UXSeparator/>
        <Intersoft:UXMenuItem Header="Exit" Command="{Binding ExitCommand}"/>
    </Intersoft:UXMenuItem>
    <Intersoft:UXMenuItem Header="Help">
        <Intersoft:UXMenuItem Header="About" NavigateUri="www.mycompany.com" TargetName="_blank"/>
    </Intersoft:UXMenuItem>
</Intersoft:UXMenuBar>

You can implement commanding through Command, CommandTarget and CommandParameters properties, and navigation through NavigateUri and TargetName properties.

To learn more about commanding, see Commanding Overview. To learn more about navigation, see Navigation Overview.

Customizing UXMenuBar Behaviors

There are several user experience aspects such as access key and mouse related action that you can customize using the following properties.

For more information about user exprience features that implemented in UXMenuBar, see User Experiences Overview.

Customizing UXMenuBar Appearance

You can customize the UXMenuBar appearance through the following properties.

If you need to completely customize the control appearance or if you want to change the styles of each visual states, you can edit the template of the control and do the modification accordingly. To learn more how to change the template and the visual states, see Styles and Template Overview.

Understanding UXMenuBarStyleSelector

UXMenuBar uses ItemContainerStyleSelector to control the style of its UXMenuItem. The UXMenuItem at first level has different representation with the rest of UXMenuItem at subsequent level.

Considering the unique styling implementation in the UXMenuBar, it is not recommended to use ItemContainerStyle to style the item of UXMenuBar. Instead, you can edit the control template directly to get the complete style of the UXMenuBar, or use ItemContainerStyleSelector to style the items.

The following example shows how to style a UXMenuBar control.

XAML
Copy Code
<UserControl x:Class="ClientUI.Samples.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Intersoft="http://intersoft.clientui.com/schemas"    
    xmlns:vm="clr-namespace:ClientUI.Samples.ViewModels"
    mc:Ignorable="d"
    d:DesignHeight="400" d:DesignWidth="800">
        <UserControl.Resources>
                <Style x:Key="MenuVertical_Separator" TargetType="Intersoft:UXSeparator">
                        <Setter Property="Margin" Value="4,2"/>
                        <Setter Property="Background" Value="#FFD0D0D0"/>
                        <Setter Property="Orientation" Value="Vertical"/>
                </Style>
                <Style x:Key="Menu_Separator" TargetType="Intersoft:UXSeparator">
                        <Setter Property="Margin" Value="35,0,4,0"/>
                        <Setter Property="Background" Value="#FFD0D0D0"/>
                </Style>
                <Intersoft:ContainerStyleSelector x:Key="MenuItemStyleSelector">
                        <Intersoft:ContainerStyle Style="{StaticResource Menu_Separator}" TypeName="UXSeparator"/>
                </Intersoft:ContainerStyleSelector>
                <Color x:Key="MenuBarItem_Pressed">#FF313131</Color>
                <Style x:Key="MenuBarItemStyle" TargetType="Intersoft:UXMenuItem">
                        <Setter Property="DisplayMemberPath" Value="Text"/>
                        <Setter Property="PreferredPosition" Value="BottomLeft"/>
                        <Setter Property="Background" Value="Transparent"/>
                        <Setter Property="BorderThickness" Value="1"/>
                        <Setter Property="CornerRadius" Value="2"/>
                        <Setter Property="ItemContainerStyleSelector" Value="{StaticResource MenuItemStyleSelector}"/>
                        <Setter Property="IndicatorVisibility" Value="Collapsed"/>
                        <Setter Property="IsTabStop" Value="False"/>
                        <Setter Property="ContentMargin" Value="6,3"/>
                        <Setter Property="Padding" Value="1,0"/>
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="VerticalContentAlignment" Value="Center"/>
                        <Setter Property="Template">
                                <Setter.Value>
                                        <ControlTemplate TargetType="Intersoft:UXMenuItem">
                                                <Grid x:Name="RootElement" Background="{TemplateBinding Background}">
                                                        <VisualStateManager.VisualStateGroups>
                                                                <VisualStateGroup x:Name="CommonStates">
                                                                        <VisualState x:Name="Normal"/>
                                                                        <VisualState x:Name="MouseOver">
                                                                                <Storyboard>
                                                                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="AnimationElement"/>
                                                                                </Storyboard>
                                                                        </VisualState>
                                                                        <VisualState x:Name="Pressed">
                                                                                <Storyboard>
                                                                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="AnimationElement"/>
                                                                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PressedHighlight"/>
                                                                                        <ColorAnimation Duration="0" To="{StaticResource MenuBarItem_Pressed}" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="AnimationElement"/>
                                                                                </Storyboard>
                                                                        </VisualState>
                                                                        <VisualState x:Name="Disabled">
                                                                                <Storyboard>
                                                                                        <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
                                                                                </Storyboard>
                                                                        </VisualState>
                                                                        <VisualState x:Name="DisabledMouseOver">
                                                                                <Storyboard>
                                                                                        <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
                                                                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="AnimationElement"/>
                                                                                        <ColorAnimation Duration="0" To="#4CB5B5B5" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="AnimationElement"/>
                                                                                        <ColorAnimation Duration="0" To="#FFCECECE" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="AnimationElement"/>
                                                                                </Storyboard>
                                                                        </VisualState>
                                                                </VisualStateGroup>
                                                                <VisualStateGroup x:Name="CheckedStates">
                                                                        <VisualState x:Name="Checked">
                                                                                <Storyboard>
                                                                                        <ColorAnimation Duration="0" To="#33AECFF7" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="IndicatorElement"/>
                                                                                        <ColorAnimation Duration="0" To="#FFAECFF7" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="IndicatorElement"/>
                                                                                </Storyboard>
                                                                        </VisualState>
                                                                        <VisualState x:Name="Unchecked"/>
                                                                </VisualStateGroup>
                                                                <VisualStateGroup x:Name="SelectionStates">
                                                                        <VisualState x:Name="Unselected"/>
                                                                        <VisualState x:Name="Selected"/>
                                                                </VisualStateGroup>
                                                        </VisualStateManager.VisualStateGroups>
                                                        <Border x:Name="AnimationElement" BorderBrush="#FF929292" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" Margin="1" Opacity="0">
                                                                <Border.Background>
                                                                        <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                                                                                <GradientStop Color="#BFFFFFFF"/>
                                                                                <GradientStop Color="#7FFFFFFF" Offset="0.5"/>
                                                                                <GradientStop Color="Transparent" Offset="0.51"/>
                                                                                <GradientStop Color="Transparent" Offset="1"/>
                                                                        </LinearGradientBrush>
                                                                </Border.Background>
                                                        </Border>
                                                        <Border x:Name="PressedHighlight" CornerRadius="{TemplateBinding CornerRadius}" Margin="{TemplateBinding BorderThickness}" Opacity="0">
                                                                <Border.Background>
                                                                        <LinearGradientBrush EndPoint="0,5" MappingMode="Absolute" StartPoint="0,0">
                                                                                <GradientStop Color="#4C000000" Offset="0"/>
                                                                                <GradientStop Color="#002B2B2B" Offset="1"/>
                                                                        </LinearGradientBrush>
                                                                </Border.Background>
                                                                <Border CornerRadius="{TemplateBinding CornerRadius}">
                                                                        <Border.Background>
                                                                                <LinearGradientBrush EndPoint="3,0" MappingMode="Absolute" StartPoint="0,0">
                                                                                        <GradientStop Color="#4C000000" Offset="0"/>
                                                                                        <GradientStop Color="#002B2B2B" Offset="1"/>
                                                                                </LinearGradientBrush>
                                                                        </Border.Background>
                                                                </Border>
                                                        </Border>
                                                        <Border BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}">
                                                                <Grid x:Name="ContentElement">
                                                                        <Grid.ColumnDefinitions>
                                                                                <ColumnDefinition Width="Auto"/>
                                                                                <ColumnDefinition/>
                                                                                <ColumnDefinition Width="Auto"/>
                                                                                <ColumnDefinition Width="Auto"/>
                                                                        </Grid.ColumnDefinitions>
                                                                        <Border x:Name="IndicatorElement" BorderBrush="Transparent" BorderThickness="1" Background="Transparent" CornerRadius="2" Margin="0" Visibility="{TemplateBinding IndicatorVisibility}">
                                                                                <ContentPresenter ContentTemplate="{TemplateBinding IconTemplate}" Height="{TemplateBinding ImageHeight}" Margin="{TemplateBinding ImageMargin}" Width="{TemplateBinding ImageWidth}">
                                                                                        <Image x:Name="IndicatorImageElement" Stretch="{TemplateBinding ImageStretch}"/>
                                                                                </ContentPresenter>
                                                                        </Border>
                                                                        <Grid Grid.Column="1">
                                                                                <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding HeaderTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding ContentMargin}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                                                        </Grid>
                                                                        <Grid Grid.Column="3" Visibility="Collapsed">
                                                                                <TextBlock x:Name="TextCommandElement" Margin="0,0,8,0" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
                                                                        </Grid>
                                                                        <Grid Grid.Column="4" Margin="3,0" Visibility="Collapsed">
                                                                                <Path x:Name="PointerElement" Data="M0,0 L0,8 L4,4 z" Fill="Black" HorizontalAlignment="Center" Margin="4,0,4,0" VerticalAlignment="Center"/>
                                                                        </Grid>
                                                                </Grid>
                                                        </Border>
                                                        <Intersoft:UXMenu x:Name="MenuElement" BoundaryOffset="{TemplateBinding BoundaryOffset}" DisplayAnimation="{TemplateBinding DisplayAnimation}" EnableFadeOutAnimation="{TemplateBinding EnableFadeOutAnimation}" EnableFadeInAnimation="{TemplateBinding EnableFadeInAnimation}" HideAnimation="{TemplateBinding HideAnimation}" HorizontalOffset="{TemplateBinding HorizontalOffset}" IsOpen="{TemplateBinding IsOpen}" PreferredVerticalDirection="{TemplateBinding PreferredVerticalDirection}" PreferredPosition="{TemplateBinding PreferredPosition}" PreferredHorizontalDirection="{TemplateBinding PreferredHorizontalDirection}" SlideDirection="{TemplateBinding SlideDirection}" VerticalOffset="{TemplateBinding VerticalOffset}">
                                                                <ItemsPresenter x:Name="ItemsPresenter" Margin="{TemplateBinding Padding}"/>
                                                        </Intersoft:UXMenu>
                                                </Grid>
                                        </ControlTemplate>
                                </Setter.Value>
                        </Setter>
                </Style>
                <Style x:Key="UXMenuBarStyle1" TargetType="Intersoft:UXMenuBar">
                        <Setter Property="Background" Value="#FFF0F0F0"/>
                        <Setter Property="BorderBrush" Value="#FF979797"/>
                        <Setter Property="CornerRadius" Value="0"/>
                        <Setter Property="IndicatorBorderBrush" Value="#FFDADADA"/>
                        <Setter Property="IndicatorBorderThickness" Value="0,0,1,0"/>
                        <Setter Property="IndicatorSpace" Value="30"/>
                        <Setter Property="ItemContainerStyleSelector">
                                <Setter.Value>
                                        <Intersoft:UXMenuBarStyleSelector MenuBarItemStyle="{StaticResource MenuBarItemStyle}">
                                                <Intersoft:ContainerStyle Style="{StaticResource MenuVertical_Separator}" TypeName="UXSeparator"/>
                                        </Intersoft:UXMenuBarStyleSelector>
                                </Setter.Value>
                        </Setter>
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="ItemsPanel">
                                <Setter.Value>
                                        <ItemsPanelTemplate>
                                                <Intersoft:WrapPanel Orientation="Horizontal"/>
                                        </ItemsPanelTemplate>
                                </Setter.Value>
                        </Setter>
                        <Setter Property="Padding" Value="1"/>
                        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                        <Setter Property="Template">
                                <Setter.Value>
                                        <ControlTemplate TargetType="Intersoft:UXMenuBar">
                                                <Grid x:Name="RootElement">
                                                        <Border x:Name="BackgroundElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}">
                                                                <ItemsPresenter x:Name="ItemsPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                                        </Border>
                                                </Grid>
                                        </ControlTemplate>
                                </Setter.Value>
                        </Setter>
                </Style>
        </UserControl.Resources>
        
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.DataContext>
            <vm:MainPageViewModel/>
        </Grid.DataContext>
        <Intersoft:UXMenuBar VerticalAlignment="Top" HorizontalAlignment="Left" Width="150" 
                             ItemsSource="{Binding Items}" DisplayMemberPath="Text" CollectionMemberPath="SubItems" Style="{StaticResource UXMenuBarStyle1}">           

        </Intersoft:UXMenuBar>
    </Grid>


</UserControl>
See Also