Custom Menubar Implementation

2 posts, 0 answers
  1. Anita
    Anita avatar
    15 posts
    Member since:
    Aug 2010

    Posted 08 Sep 2010 Link to this post

    Hi,

    We are implementing a custom menu bar for which RadMenu is the underlying control using template approach (controltemplate).

    We are able to bind all properties but coming to UI part, our custom control is just showing the menubar with the header items and when we click on
    any menuitem, the sub menu's are not showing up.

    We couldn't figure what was the actual problem here.

    We hope you can give a helping hand in this regard.

    Below is the code snippet for generic.xaml......

     

     

     

    <Style TargetType="local:TngMenuBar">

     

     

     

     

    <Setter Property="Background"

     

     

     

    Value="White" />

     

     

     

     

    <Setter Property="Foreground"

     

     

     

    Value="Black" />

     

     

     

     

    <Setter Property="BorderBrush"

     

     

     

    Value="Black" />

     

     

     

     

    <Setter Property="BorderThickness"

     

     

     

    Value="1" />

     

     

     

     

    <Setter Property="Template">

     

     

     

     

    <Setter.Value>

     

     

     

     

    <ControlTemplate TargetType="local:TngMenuBar">

     

     

     

     

    <ControlsNavigation:RadMenu Name="PART_TngMenuBar"

     

     

     

    DataContext="{TemplateBinding Property=DataContext}"

     

     

     

    ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"

     

     

     

    ItemTemplate="{TemplateBinding Property=ItemTemplate}"

     

     

     

    ItemTemplateSelector="{TemplateBinding Property=ItemTemplateSelector}"

     

     

     

    ItemContainerStyle="{TemplateBinding Property=ItemContainerStyle}"

     

     

     

    ItemContainerStyleSelector="{TemplateBinding Property=ItemContainerStyleSelector}"

     

     

     

    FontSize="{TemplateBinding Property=FontSize}"

     

     

     

    FontStyle="{TemplateBinding Property=FontStyle}"

     

     

     

    Foreground="{TemplateBinding Property=Foreground}"

     

     

     

    ClickToOpen="{TemplateBinding Property=ClickToOpen}"

     

     

     

    ShowDelay="{TemplateBinding Property=ShowDelay}"

     

     

     

    HideDelay="{TemplateBinding Property=HideDelay}"

     

     

     

    Orientation="{TemplateBinding Property=Orientation}"

     

     

     

    >

     

     

     

     

     

    </ControlsNavigation:RadMenu>

     

     

     

     

     

    </ControlTemplate>

     

     

     

     

    </Setter.Value>

     

     

     

     

    </Setter>

     

     

     

     

     

     

    </Style>

     

     

     

     

    <Style TargetType="local:TngMenuItem">

     

     

     

     

     

    <Setter Property="Template">

     

     

     

     

    <Setter.Value>

     

     

     

     

    <ControlTemplate TargetType="local:TngMenuItem">

     

     

     

     

    <ControlsNavigation:RadMenuItem Name="PART_TngMenuBarItem"

     

     

     

    Header="{TemplateBinding Property=Header}"

     

     

     

    ></ControlsNavigation:RadMenuItem>

     

     

     

     

    </ControlTemplate>

     

     

     

     

    </Setter.Value>

     

     

     

     

    </Setter>

     

     

     

     

    </Style>

     


    Below is the code snippet for our custom control Menubar.cs code......

     

     

    public class TngMenuBar : Control

     

    {

    #region

     

     

    Constructors

     

     

     

    public TngMenuBar()

     

    {

    DefaultStyleKey =

     

    typeof(TngMenuBar);

     

    Items =

     

    new TngMenuBarItemCollection();

     

     

     

     

    }

    #endregion

     

     

     

    public static DependencyProperty ItemsProperty = DependencyProperty.Register(

     

     

     

    "Items",

     

     

     

    typeof(TngMenuBarItemCollection),

     

     

     

    typeof(TngMenuBar),

     

     

     

    null);

     

     

     

    public TngMenuBarItemCollection Items

     

    {

     

     

    get { return this.GetValue(ItemsProperty) as TngMenuBarItemCollection; }

     

     

     

    set { this.SetValue(ItemsProperty, value); }

     

    }

     

     

     

    public event RoutedEventHandler ItemClick;

     

     

     

    void TngMenu_MouseLeftButtonUp(object sender,

     

     

     

    MouseButtonEventArgs e)

     

    {

     

     

    if (ItemClick != null)

     

    ItemClick(

     

    this, new RoutedEventArgs());

     

    }

     

     

     

     

    public override void OnApplyTemplate()

     

    {

     

     

    base.OnApplyTemplate();

     

     

     

     

    RadMenu menu = this.GetTemplateChild("PART_TngMenuBar") as RadMenu;

     

     

     

    if (menu == null)

     

     

     

    return;

     

     

     

     

    for (int i = 0; i < this.Items.Count; i++)

     

    {

     

     

    TngMenuItem menuItem = this.Items[i];

     

     

    menu.Items.Add(menuItem);

    }

    }

    #region

     

     

    Property: DataContext

     

     

     

    private Object _dataContext;

     

     

     

    public Object DataContext

     

    {

     

     

    get { return GetValue(DataContextProperty); }

     

     

     

    set { SetValue(DataContextProperty, value); }

     

    }

     

     

    public static readonly DependencyProperty DataContextProperty =

     

     

     

    DependencyProperty.Register(

     

     

     

    "DataContext", typeof(Object), typeof(TngMenuBar),

     

     

     

    new PropertyMetadata((o, e) =>

     

    {

    ((

     

    TngMenuBar)o).UpdateDataContext((Object)e.NewValue);

     

    }));

     

     

     

    private void UpdateDataContext(Object sel)

     

    {

    _dataContext = sel;

    }

    #endregion

    #region

     

     

    Property: ItemsSource

     

     

     

    private IEnumerable _itemsSource;

     

     

     

    public IEnumerable ItemsSource

     

    {

     

     

    get { return (IEnumerable)GetValue(ItemsSourceProperty); }

     

     

     

    set { SetValue(ItemsSourceProperty, value); }

     

    }

     

     

    public static readonly DependencyProperty ItemsSourceProperty =

     

     

     

    DependencyProperty.Register(

     

     

     

    "ItemsSource", typeof(IEnumerable), typeof(TngMenuBar),

     

     

     

    new PropertyMetadata((o, e) =>

     

    {

    ((

     

    TngMenuBar)o).UpdateItemsSource((IEnumerable)e.NewValue);

     

    }));

     

     

    private void UpdateItemsSource(IEnumerable sel)

     

    {

    _itemsSource = sel;

    }

    #endregion

    #region

     

     

    Property: ItemTemplate

     

     

     

    private DataTemplate _itemTemplate;

     

     

     

    public DataTemplate ItemTemplate

     

    {

     

     

    get { return (DataTemplate)GetValue(ItemTemplateProperty); }

     

     

     

    set { SetValue(ItemTemplateProperty, value); }

     

    }

     

     

    public static readonly DependencyProperty ItemTemplateProperty =

     

     

     

    DependencyProperty.Register(

     

     

     

    "ItemTemplate", typeof(DataTemplate), typeof(TngMenuBar),

     

     

     

    new PropertyMetadata((o, e) =>

     

    {

    ((

     

    TngMenuBar)o).UpdateItemTemplate((DataTemplate)e.NewValue);

     

    }));

     

     

    private void UpdateItemTemplate(DataTemplate sel)

     

    {

    _itemTemplate = sel;

    }

    #endregion

    #region

     

     

    Property: ItemTemplateSelector

     

     

     

    private DataTemplateSelector _itemTemplateSelector;

     

     

     

    public DataTemplateSelector ItemTemplateSelector

     

    {

     

     

    get { return (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); }

     

     

     

    set { SetValue(ItemTemplateSelectorProperty, value); }

     

    }

     

     

    public static readonly DependencyProperty ItemTemplateSelectorProperty =

     

     

     

    DependencyProperty.Register(

     

     

     

    "ItemTemplateSelector", typeof(DataTemplateSelector), typeof(TngMenuBar),

     

     

     

    new PropertyMetadata((o, e) =>

     

    {

    ((

     

    TngMenuBar)o).UpdateItemTemplateSelector((DataTemplateSelector)e.NewValue);

     

    }));

     

     

    private void UpdateItemTemplateSelector(DataTemplateSelector sel)

     

    {

    _itemTemplateSelector = sel;

    }

    #endregion

    #region

     

     

    Property: ItemContainerStyle

     

     

     

    private Style _itemContainerStyle;

     

     

     

    public Style ItemContainerStyle

     

    {

     

     

    get { return (Style)GetValue(ItemContainerStyleProperty); }

     

     

     

    set { SetValue(ItemContainerStyleProperty, value); }

     

    }

     

     

    public static readonly DependencyProperty ItemContainerStyleProperty =

     

     

     

    DependencyProperty.Register(

     

     

     

    "ItemContainerStyle", typeof(Style), typeof(TngMenuBar),

     

     

     

    new PropertyMetadata((o, e) =>

     

    {

    ((

     

    TngMenuBar)o).UpdateItemContainerStyle((Style)e.NewValue);

     

    }));

     

     

    private void UpdateItemContainerStyle(Style sel)

     

    {

    _itemContainerStyle = sel;

    }

    #endregion


    Below is the code snippet for our custom control MenuItem.cs code......

     

     

     

    public class TngMenuItem:ContentControl

     

     

     

     

     

     

    {

     

     

     

     

     

    #region

     

     

    Constructors

     

     

     

    public TngMenuItem()

     

    {

    DefaultStyleKey =

     

    typeof(TngMenuItem);

     

    Items =

     

    new TngMenuBarItemCollection();

     

    }

     

     

     

     

    #endregion

     

     

     

     

     

     

     

    public static DependencyProperty ItemsProperty = DependencyProperty.Register(

     

     

     

    "Items",

     

     

     

    typeof(TngMenuBarItemCollection),

     

     

     

    typeof(TngMenuItem),

     

     

     

    null);

     

     

     

    public TngMenuBarItemCollection Items

     

    {

     

     

    get { return this.GetValue(ItemsProperty) as TngMenuBarItemCollection; }

     

     

     

    set { this.SetValue(ItemsProperty, value); }

     

    }

     

     

    public override void OnApplyTemplate()

     

    {

     

     

    base.OnApplyTemplate();

     

     

     

     

    RadMenuItem menuitem = this.GetTemplateChild("PART_TngMenuBarItem") as RadMenuItem;

     

     

     

    if (menuitem == null)

     

     

     

    return;

     

     

     

    for (int i = 0; i < this.Items.Count; i++)

     

    {

     

     

    TngMenuItem cmi = this.Items[i];

     

     

    menuitem.Items.Add(cmi);

    }

    }

     

     

     

     

     

     

    #region

     

     

    Property: Header

     

     

     

    private Object _header;

     

     

     

    public virtual Object Header

     

    {

     

     

    get { return GetValue(HeaderProperty); }

     

     

     

    set { SetValue(HeaderProperty, value); }

     

    }

     

     

    public static readonly DependencyProperty HeaderProperty =

     

     

     

    DependencyProperty.Register(

     

     

     

    "Header", typeof(Object), typeof(TngMenuItem),

     

     

     

    new PropertyMetadata((o, e) =>

     

    {

    ((

     

    TngMenuItem)o).UpdateHeader((Object)e.NewValue);

     

    }));

     

     

    private void UpdateHeader(Object sel)

     

    {

    _header = sel;

    }

     

     

     

     

    #endregion

    Below is the code snippet for our custom control MenuItemcollection.cs code......

     

     

     

    public class TngMenuBarItemCollection : ObservableCollection<TngMenuItem>

     

    {

    }

     

     



     

  2. Pana
    Admin
    Pana avatar
    748 posts

    Posted 14 Sep 2010 Link to this post

    Hi Anita,

    Perhaps you should set the ItemsSource on the MenuItem also. Setting it on the Menu will display the first (top) level items but if you want to display hierarchical structure (with sub menus) the MenuItems need their ItemsSource set too.

    Regards,
    Panayot
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
Back to Top