带用户控制的垂直左侧菜单(内部扩展器)必须在您打开一个时关闭其他菜单 XAML

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

我正在实现一个带有用户控件的垂直左下拉菜单,它在扩展器中。 UserControl 有一个 DependencyProperty,它需要一个 ListView(菜单项),还有一个依赖项 属性“IsSelected”,它与 Expander 属性“IsExpanded”绑定。我喜欢在用户单击 UserControlMenu 时实现一个功能,打开它(如果已关闭)并关闭其他功能。我附上了我的 类 和 UserControl,但是,现在只有当您单击 UserControlMenu 时,我才能看到它打开并立即关闭。

用户控件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>

用户控件.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;
        }
    }

在主窗口中调用用户控件

<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;
                    }
                }
            }
        }
    }

你应该设置eventArgs.Handled = true;,它会阻止事件冒泡,比如:

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
        }
    }
}