This is a migrated thread and some comments may be shown as answers.

Custom Menubar Implementation

1 Answer 91 Views
Menu
This is a migrated thread and some comments may be shown as answers.
Anita
Top achievements
Rank 1
Anita asked on 08 Sep 2010, 02:32 PM
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>

 

{

}

 

 



 

1 Answer, 1 is accepted

Sort by
0
Pana
Telerik team
answered on 14 Sep 2010, 06:50 AM
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
Tags
Menu
Asked by
Anita
Top achievements
Rank 1
Answers by
Pana
Telerik team
Share this question
or