wpf - 当您打开一个 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;
}
}
在 MainWindow 中调用 UserControl
<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>
主窗口.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
}
}
}
推荐阅读
- php - 在 html标签中显示来自 curl 请求的图像
- apache-kafka - Kafka 消费者何时重试?
- ffmpeg - FFMPEG 在剪辑结束时切断音频
- apache-kafka - LogCompaction and consumer in Kafka
- r - Create sequence of values based on multiple column values in R
- node.js - How do I get my async function to return values not a promise?
- makefile - ocamlbuild: Nothing to be done for `all'
- botframework - 是否可以在自适应卡上实现简单的计数器?就像每次单击提交按钮时,文本块中的值都会增加
- solr - SOLR 索引任意数据
- google-cloud-platform - 如何从命令行设置/获取 json 格式的气流变量