Custom Rad Menu Item

3 posts, 1 answers
  1. Mahesh
    Mahesh avatar
    7 posts
    Member since:
    Nov 2012

    Posted 03 Dec 2012 Link to this post

    Hi,

                    I’m trying to create Custom RadMenuItem. So that i can override mouseleave event to have my own visual state properties. But i'm not sure how to bind CustomRadMenuItem to my Custom RadMenu.cs. I've copied both xaml file and .cs files below FYR

     I’m getting exception at PrepareContainerForItemOverride  method in my Custom RadMenu.CS file,
    1. base.PrepareContainerForItemOverride (element,item) is throwing exception.
    2. unable to cast Telerik.Windows.Controls.RadMenuItem to CustomRadMenuItem.

    Can you please help me on this?

    Regards,
    Mahesh.

    XAML File:
     
     
        <ControlTemplate x:Key="NavBarTopLevelHeaderTemplate" TargetType="local:CustomRadMenuItem">
            <Grid >
                <Rectangle x:Name="BackgroundVisual" Fill="#FFe8f2ff" Opacity="0" />
                <TextBlock x:Name="TextElement" Text="{Binding Title}" TextDecorations="None" Foreground="White" FontFamily="Arial" Margin="10,6,20,6" HorizontalAlignment="Right" VerticalAlignment="Stretch" FontSize="12" />
                <Path x:Name="DropDownArrow" Fill="White" Data="M0,0 L2,0 1,1" Stretch="Uniform" Width="7" Height="5" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="4,0,10,0" />
                <Popup x:Name="PART_Popup" HorizontalOffset="-1" VerticalOffset="-1" MaxHeight="250">
                    <Border x:Name="PopupContent" Margin="0 1 0 0" BorderBrush="{StaticResource MenuDropDownBorder}" BorderThickness="1,0,1,1"  Background="{StaticResource MenuDropDownBackground}" Padding="6" CornerRadius="0,4,4,4">
                        <Border BorderThickness="1">
                            <ItemsPresenter Margin="8 4" />
                        </Border>
                    </Border>
                </Popup>
     
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualStateGroup.Transitions>
                            <VisualTransition GeneratedDuration="0:0:0.2"/>
                        </VisualStateGroup.Transitions>
                        <VisualState x:Name="Unfocused" />
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="Focused">
                            <!--<Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundVisual" Storyboard.TargetProperty="Opacity">
                                    <LinearDoubleKeyFrame KeyTime="00:00:00.1" Value="1" />
                                </DoubleAnimationUsingKeyFrames>
                                <ColorAnimation Duration="0" To="#FF1061a1"  Storyboard.TargetName="TextElement" Storyboard.TargetProperty="(TextBlock.ForeGround).(SolidColorBrush.Color)" />
                                <ColorAnimation Duration="0" To="#FF1061a1"  Storyboard.TargetName="DropDownArrow" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" />
                            </Storyboard>-->
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
     
            </Grid>
        </ControlTemplate>
     
        <ControlTemplate x:Key="NavBarTopLevelItemTemplate" TargetType="local:CustomRadMenuItem">
            <Grid >
                <Rectangle x:Name="BackgroundVisual" Fill="#FFe8f2ff" Opacity="0" />
                 
     
                <TextBlock x:Name="TextElement" Text="{Binding Title}" TextDecorations="None"  Foreground="White" FontFamily="Arial"   Margin="10,6" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="12" />
     
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CheckStates">
                        <VisualState x:Name="Checked">
                            <Storyboard >
                                 
                                 
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundVisual" Storyboard.TargetProperty="Opacity">
                                        <LinearDoubleKeyFrame KeyTime="00:00:00.1" Value="1" />
                                    </DoubleAnimationUsingKeyFrames>
                                    <ColorAnimation Duration="0" To="#FF1061a1"  Storyboard.TargetName="TextElement" Storyboard.TargetProperty="(TextBlock.ForeGround).(SolidColorBrush.Color)" />
                                </Storyboard>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Unchecked"/>
                        <VisualState x:Name="HideIcon"/>
                    </VisualStateGroup>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Disabled"/>
                        <VisualState x:Name="Highlighted">
                            <Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundVisual" Storyboard.TargetProperty="Opacity">
                                    <LinearDoubleKeyFrame KeyTime="00:00:00.1" Value="1" />
                                </DoubleAnimationUsingKeyFrames>
                                <ColorAnimation Duration="0" To="#FF1061a1"  Storyboard.TargetName="TextElement" Storyboard.TargetProperty="(TextBlock.ForeGround).(SolidColorBrush.Color)" />
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Normal"/>
                    </VisualStateGroup>
                    <VisualStateGroup x:Name="FocusStates">
                        <VisualStateGroup.Transitions>
                            <VisualTransition GeneratedDuration="0:0:0.2"/>
                        </VisualStateGroup.Transitions>
                        <VisualState x:Name="Unfocused" />
                        <VisualState x:Name="Focused">
                             
                             
                        </VisualState>
                        <VisualState x:Name="MouseOver">
                             
                        </VisualState>
                    </VisualStateGroup>
     
                </VisualStateManager.VisualStateGroups>
     
            </Grid>
        </ControlTemplate>
     
        <Style x:Key="NavigationStyle" TargetType="local:CustomRadMenuItem">
            <Setter Property="Template" Value="{StaticResource NavBarTopLevelHeaderTemplate}"/>
            <Setter Property="SeparatorTemplateKey" Value="{StaticResource NavBarTopLevelHeaderTemplate}"/>
            <Setter Property="SubmenuItemTemplateKey" Value="{StaticResource NavBarTopLevelHeaderTemplate}"/>
            <Setter Property="TopLevelHeaderTemplateKey" Value="{StaticResource NavBarTopLevelHeaderTemplate}"/>
            <Setter Property="TopLevelItemTemplateKey" Value="{StaticResource NavBarTopLevelItemTemplate}"/>
            <Setter Property="SubmenuHeaderTemplateKey" Value="{StaticResource NavBarTopLevelHeaderTemplate}"/>
             
            <Setter Property="IsCheckable" Value="True"/>
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <toolkit:WrapPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
     
            <Setter Property="telerik:AnimationManager.AnimationSelector">
                <Setter.Value>
                    <telerik:AnimationSelector>
                        <telerik:SlideAnimation Direction="In" SlideMode="Top" AnimationName="Expand" TargetElementName="PopupContent" />
                    </telerik:AnimationSelector>
                </Setter.Value>
            </Setter>
     
        </Style>
     
        <local:NavigationMenuStyleSelector x:Key="navigationPanelStyleSelector"
                                           FirstLevelWithViewStyle="{StaticResource NavigationStyle}"
                                           FirstLevelWithChildrenStyle="{StaticResource NavigationStyle}"
                                           FirstLevelWithBothStyle="{StaticResource NavigationStyle}"
                                            
                                           SecondLevelWithViewStyle="{StaticResource MenuItem2WithViewsStyle}"
                                           SecondLevelWithChildrenStyle="{StaticResource MenuItem2WithChildrenStyle}"
                                           SecondLevelWithBothStyle="{StaticResource MenuItem2WithBothStyle}"
                                            
                                           AdditionalLevelWithViewStyle="{StaticResource MenuItem2WithViewsStyle}"
                                           AdditionalLevelWithChildrenStyle="{StaticResource MenuItem2WithChildrenStyle}"
                                           AdditionalLevelWithBothStyle="{StaticResource MenuItem2WithBothStyle}"
                                           />
     
     
        <Style TargetType="local:NavigationBar">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:NavigationBar">
                        <Border d:DataContext="{Binding SelectedModule, Source={StaticResource SampleApplicationViewModel}}" DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"  Opacity="0.7" BorderThickness="0" Background="#FF105E9E"
                        d:DesignHeight="30" d:DesignWidth="800"
                                VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                            <local:RadMenu Margin="20,0,20,0" ItemsSource="{Binding NavigationTree}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                                                  ItemContainerStyleSelector="{StaticResource navigationPanelStyleSelector}" Background="{x:Null}" VerticalContentAlignment="Stretch">
                                <local:RadMenu.ItemTemplate>
                                    <telerik:HierarchicalDataTemplate ItemsSource="{Binding Children}">
                                        <telerik:ContainerBinding.ContainerBindings>
                                            <telerik:ContainerBindingCollection>
                                                <telerik:ContainerBinding PropertyName="Icon" Binding="{Binding SmallIcon}" />
                                                <telerik:ContainerBinding PropertyName="Command" Binding="{Binding OpenView}" />
                                                <telerik:ContainerBinding PropertyName="Header" Binding="{Binding Title}" />
                                            </telerik:ContainerBindingCollection>
                                        </telerik:ContainerBinding.ContainerBindings>
                                        <TextBlock Text="{Binding Title}" />
                                    </telerik:HierarchicalDataTemplate>
                                </local:RadMenu.ItemTemplate>
                            </local:RadMenu>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    public class RadMenu : Telerik.Windows.Controls.RadMenu
        {
            /// <summary>
            /// Set the default style.
            /// </summary>
            public RadMenu()
            {
                this.DefaultStyleKey = typeof(RadMenu);
                 
            }
     
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
            {
                base.PrepareContainerForItemOverride(element, item);
                DrillDownViewModel viewModel = (DrillDownViewModel)item;
                CustomRadMenuItem menuItem = (CustomRadMenuItem)element;
                IViewsViewModel viewsViewModel = ServiceLocator.Current.Resolve<IViewsViewModel>();
                IViewViewModel detailView = viewsViewModel.ActiveViews.FirstOrDefault<IViewViewModel>(vm => vm.DockPosition == DockPosition.MainView);
                if (detailView != null && detailView.Title == viewModel.Title )
                {
                    menuItem.IsChecked = true;
                }
               
            }
    }
    public class CustomRadMenuItem : Telerik.Windows.Controls.RadMenuItem
          {
            /// <summary>
            /// Set the default style.
            /// </summary>
            public CustomRadMenuItem ()
            {
                this.DefaultStyleKey = typeof(RadMenuItem);
                 
            }
  2. Answer
    Rosen Vladimirov
    Admin
    Rosen Vladimirov avatar
    640 posts

    Posted 04 Dec 2012 Link to this post

    Hello Mahesh,

    The problem is that in PrepareContainerForItemOverride() element is RadMenuItem. To fix this you have to override GetContainerForItemOverride(). The idea is that when you use MVVM you have to define the container that will be set on your items. By default for RadMenu all items are wrapped in RadMenuItem, but in your case this is not what you need. In PrepareContainerForItemOverride() the container is already defined, so it is too late to set it, that's why you have to override GetContainerForItemOverride(). Here's how your code should work:
    public class RadMenu : Telerik.Windows.Controls.RadMenu
    {
        /// <summary>
        /// Set the default style.
        /// </summary>
        public RadMenu()
        {
            this.DefaultStyleKey = typeof(RadMenu);
        }
     
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new CustomRadMenuItem();
        }
     
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return base.IsItemItsOwnContainerOverride(item);
        }
      
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
            DrillDownViewModel viewModel = (DrillDownViewModel)item;
            CustomRadMenuItem menuItem = (CustomRadMenuItem)element;
            IViewsViewModel viewsViewModel = ServiceLocator.Current.Resolve<IViewsViewModel>();
            IViewViewModel detailView = viewsViewModel.ActiveViews.FirstOrDefault<IViewViewModel>(vm => vm.DockPosition == DockPosition.MainView);
            if (detailView != null && detailView.Title == viewModel.Title )
            {
                menuItem.IsChecked = true;
            }
        }
     
        protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        {
            // Clear the data set in PrepareContainerForItemOverride...
            base.ClearContainerForItemOverride(element, item);
        }
    }

    Please try it in your application and inform us if you still have any problems or concerns.

    All the best,
    Rosen Vladimirov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. DevCraft banner
  4. Mahesh
    Mahesh avatar
    7 posts
    Member since:
    Nov 2012

    Posted 05 Dec 2012 Link to this post

    Works Perfect ! Thanks Rosen.
Back to Top