Home > Software design >  Vertical Left Menu with User Control (Expander inside) must close others when you open one XAML
Vertical Left Menu with User Control (Expander inside) must close others when you open one XAML

Time:09-17

I'm implementing a Vertical Left Drop Down Menu with an User Control, this has inside an Expander. The UserControl has a DependencyProperty which expect a ListView (The Items of the Menu), also has a dependency property "IsSelected" which is bind with Expander property "IsExpanded". I like implement a function when the user click in the UserControlMenu, open this (if is Closed) and close the others. I attached my classes and UserControl, but, now I'm only get when you click on the UserControlMenu, this open and in that instant close.

The UserControl XAML

<UserControl x:Class="DropDownMenuExpander.UserControlMenuItem"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
             mc:Ignorable="d" >
    <Grid>
        <md:PackIcon Kind="{Binding Path=Icon}" Width="15" Height="15" Margin="10 16"/>
        <Expander x:Name="ExpanderMenu" Header="{Binding Path=Header}" IsExpanded="{Binding Path=IsSelected}" Width="210" HorizontalAlignment="Right" Background="{x:Null}">
            <ContentControl Content="{Binding ListView}"/>
        </Expander>
    </Grid>
</UserControl>

The UserControl .cs

    public partial class UserControlMenuItem : UserControl
    {
        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(UserControlMenuItem));
        public string Header
        {
            get
            {
                return (string)GetValue(HeaderProperty);
            }
            set
            {
                SetValue(HeaderProperty, value);
            }
        }

        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(UserControlMenuItem));
        public bool IsSelected
        {
            get
            {
                return (bool)GetValue(IsSelectedProperty);
            }
            set
            {
                SetValue(IsSelectedProperty, value);
            }
        }


        public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(PackIconKind), typeof(UserControlMenuItem));
        public PackIconKind Icon
        {
            get
            {
                return (PackIconKind)GetValue(IconProperty);
            }
            set
            {
                SetValue(IconProperty, value);
            }
        }
        public static readonly DependencyProperty ListViewProperty = DependencyProperty.Register("ListView", typeof(ListView), typeof(UserControlMenuItem), new UIPropertyMetadata(null));
        public ListView ListView
        {
            get
            {
                return (ListView)GetValue(ListViewProperty);
            }
            set
            {
                SetValue(ListViewProperty, value);
            }
        }
        public UserControlMenuItem()
        {
            InitializeComponent();
            DataContext = this;
        }
    }

Calling the UserControl in the MainWindow

<StackPanel x:Name="st_menu" Margin="10" Orientation="Vertical" ScrollViewer.CanContentScroll="True">
                    <local:UserControlMenuItem  x:Name="MenuItemHome" Header="Home" Icon="Home" PreviewMouseDown="MenuItemHome_PreviewMouseDown">
                        <local:UserControlMenuItem.ListView>
                            <ListView SelectionMode="Single" Margin="0 16 0 16">
                                <ListViewItem>
                                    <TextBlock Text="Item1"/>
                                </ListViewItem>
                                <ListViewItem>
                                    <TextBlock Text="Item2"/>
                                </ListViewItem>
                                <ListViewItem>
                                    <TextBlock Text="Item3"/>
                                </ListViewItem>
                            </ListView>
                        </local:UserControlMenuItem.ListView>
                    </local:UserControlMenuItem>
                    <local:UserControlMenuItem  x:Name="MenuItem2" Header="User" Icon="User" PreviewMouseDown="MenuItemHome_PreviewMouseDown">
                        <local:UserControlMenuItem.ListView>
                            <ListView SelectionMode="Single" Margin="0 16 0 16">
                                <ListViewItem>
                                    <TextBlock Text="User1"/>
                                </ListViewItem>
                                <ListViewItem>
                                    <TextBlock Text="User2"/>
                                </ListViewItem>
                                <ListViewItem>
                                    <TextBlock Text="User3"/>
                                </ListViewItem>
                            </ListView>
                        </local:UserControlMenuItem.ListView>
                    </local:UserControlMenuItem>
                    <local:UserControlMenuItem  x:Name="MenuMes2" Header="Messages" Icon="Chat" PreviewMouseDown="MenuItemHome_PreviewMouseDown">
                        <local:UserControlMenuItem.ListView>
                            <ListView SelectionMode="Single" Margin="0 16 0 16">
                                <ListViewItem>
                                    <TextBlock Text="Message1"/>
                                </ListViewItem>
                                <ListViewItem>
                                    <TextBlock Text="Message2"/>
                                </ListViewItem>
                                <ListViewItem>
                                    <TextBlock Text="Message3"/>
                                </ListViewItem>
                            </ListView>
                        </local:UserControlMenuItem.ListView>
                    </local:UserControlMenuItem>
                </StackPanel>

MainWindow.cs

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MenuItemHome.IsSelected = true;
        }

        private void MenuItemHome_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            foreach (var item in st_menu.Children)
            {
                if (item is UserControlMenuItem menuItem)
                {
                    if (menuItem.Equals(sender as UserControlMenuItem))
                    {
                        menuItem.IsSelected = true;
                    }
                    else
                    {
                        menuItem.IsSelected = false;
                    }
                }
            }
        }
    }

CodePudding user response:

You should set eventArgs.Handled = true;, it will stop the event bubbling, like:

private void MenuItemHome_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    foreach (var item in st_menu.Children)
    {
        if (item is UserControlMenuItem menuItem && sender is UserControlMenuItem senderItem)
        {
            menuItem.IsSelected = menuItem.Equals(senderItem) && !senderItem.IsSelected;                
            e.Handled = true; //Tells to the visual tree that event was already handled
        }
    }
}
  • Related