noName NoName

noName NoName

  • NA
  • 6
  • 10.9k

Popup control is returned always null ???

Mar 26 2012 10:02 AM
Hi ,

I am trying to add sub menu to a context menu. After some research, I find a helpful link.

http://technologywanderer.wordpress.com/2010/06/18/silverlight-4-custom-menuitem-control-with-sub-items/

I tried to implement the code in my project. But the pop up menu is returned null always . I researched the error, but I couldn't find any helpful solution.There is a class which implements MenuItem :

using System;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace SilverlightEnhancedMenuItem
{
    public class SuperMenuItem : MenuItem
    {
        #region Fields

        private Popup popup;
        public bool CanLeave { get; set; }

        #endregion

        #region Properties

        public Visibility HasSubItems
        {
            get { return (Visibility)GetValue(HasSubItemsProperty); }
            set { SetValue(HasSubItemsProperty, value); }
        }

        public static readonly DependencyProperty HasSubItemsProperty =
            DependencyProperty.Register("HasSubItems", typeof(Visibility), typeof(SuperMenuItem), new PropertyMetadata(Visibility.Collapsed));

        public bool IsSubmenuOpen
        {
            get { return (bool)GetValue(IsSubmenuOpenProperty); }
            set { SetValue(IsSubmenuOpenProperty, value); }
        }

        public static readonly DependencyProperty IsSubmenuOpenProperty =
            DependencyProperty.Register("IsSubmenuOpen", typeof(bool), typeof(SuperMenuItem), new PropertyMetadata(false));

        #endregion

        #region Constructor

        public SuperMenuItem()
        {
            this.DefaultStyleKey = typeof(SuperMenuItem);
            this.MouseEnter += new MouseEventHandler(parent_MouseEnter);
            this.MouseLeave += new MouseEventHandler(SuperMenuItem_MouseLeave);
            this.Click += new RoutedEventHandler(SuperMenuItem_Click);
            this.CanLeave = true;
        }

        private void SuperMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (this.Parent != null && this.Parent is SuperMenuItem)
            {
                (this.Parent as SuperMenuItem).OnClick();
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            popup = (Popup)this.GetTemplateChild("PART_Popup");
            popup.Opened += new EventHandler(popup_Opened);
            popup.Closed += new EventHandler(popup_Closed);
        }

        private void popup_Opened(object sender, EventArgs e)
        {
            this.CanLeave = false;
        }

        private void popup_Closed(object sender, EventArgs e)
        {
            if (this.HasSubItems == Visibility.Visible)
            {
                this.IsSubmenuOpen = false;
            }
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems.Count > 0)
            {
                this.HasSubItems = Visibility.Visible;
            }
        }

        private void parent_MouseEnter(object sender, MouseEventArgs e)
        {
            this.CanLeave = true;
            if (this.HasSubItems == Visibility.Visible)
            {
                this.IsSubmenuOpen = true;
            }
            if (this.Parent != null && this.Parent is ContextMenu)
            {
                foreach (var item in (this.Parent as ContextMenu).Items)
                {
                    if (item != this)
                    {
                        (item as SuperMenuItem).IsSubmenuOpen = false;
                    }
                }
            }
        }

        private void SuperMenuItem_MouseLeave(object sender, MouseEventArgs e)
        {
            if (this.HasSubItems == Visibility.Visible)
            {
                if (CanLeave)
                {
                    this.IsSubmenuOpen = false;
                }
            }
        }

        #endregion
    }

}

The style of the menu is :

      <Style TargetType="local:SuperMenuItem">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="Padding" Value="4,3,2,3"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:SuperMenuItem">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Presenter"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Unfocused"/>
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Bg"/>
                                            <ColorAnimation Duration="0" To="#40FFFFFF" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="InnerBorder"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Rectangle Fill="{TemplateBinding Background}" RadiusY="2" RadiusX="2" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="1"/>
                            <Rectangle x:Name="Bg" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#8071CBF1" StrokeThickness="1">
                                <Rectangle.Fill>
                                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                                        <GradientStop Color="#34C5EBFF" Offset="0"/>
                                        <GradientStop Color="#3481D8FF" Offset="1"/>
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                            <Rectangle x:Name="InnerBorder" Margin="1" RadiusY="2" RadiusX="2" Stroke="Transparent"/>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition MinWidth="24" Width="Auto"/>
                                    <ColumnDefinition Width="4"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="17"/>
                                </Grid.ColumnDefinitions>
                                <ContentPresenter Content="{TemplateBinding Icon}" Margin="1" VerticalAlignment="Center"/>
                                <ContentPresenter x:Name="Presenter" ContentTemplate="{TemplateBinding HeaderTemplate}"
                                                  Content="{TemplateBinding Header}" Grid.Column="2" Margin="{TemplateBinding Padding}"/>
                                <Path Grid.Column="3" Data="M 0,0 L 4,3.5 L 0,7 Z" Fill="Black"
                                      Margin="4,0,0,0" VerticalAlignment="Center" Visibility="{TemplateBinding HasSubItems}"/>
                                <!--<Path x:Name="Glyph" Data="M 0,5.1 L 1.7,5.2 L 3.4,7.1 L 8,0.4 L 9.2,0 L 3.3,10.8 Z"
                                  Fill="#0C12A1" FlowDirection="LeftToRight" Height="11" Width="9"/>-->
                            </Grid>
                            <Popup x:Name="PART_Popup" HorizontalOffset="{TemplateBinding ActualWidth}"
                                   IsOpen="{TemplateBinding IsSubmenuOpen}" Margin="-4,0,0,0">
                                <ContentControl x:Name="SubMenuBorder">
                                    <ContentControl.Template>
                                        <ControlTemplate>
                                            <Grid Background="#FFF5F5F5">
                                                <Rectangle Fill="#F1F1F1" HorizontalAlignment="Left" RadiusY="2" RadiusX="2" Width="28" />
                                                <Rectangle Fill="#E2E3E3" HorizontalAlignment="Left" Width="1" Margin="30,0,0,0"/>
                                                <Rectangle Fill="White" HorizontalAlignment="Left" Width="1" Margin="31,0,0,0"/>
                                                <ContentPresenter Grid.ColumnSpan="2" Margin="1,0"/>
                                            </Grid>
                                        </ControlTemplate>
                                    </ContentControl.Template>
                                    <ScrollViewer x:Name="SubMenuScrollViewer" VerticalScrollBarVisibility="Auto" Padding="0">
                                        <Grid>
                                            <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                                <Rectangle Fill="#FFF5F5F5" Height="{Binding ActualHeight, ElementName=SubMenuBorder}"
                                                           Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
                                            </Canvas>
                                            <ItemsPresenter x:Name="ItemsPresenter" Margin="2" />
                                        </Grid>
                                    </ScrollViewer>
                                </ContentControl>
                            </Popup>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

I added xaml to the user control which I want to see the context menu with sub menu . I think , It could not reach to the xaml which the style is defined. I still couldn't find any solution for this problem..

Thanks for the replies in advance..