Menu菜单
Menu控件继承于MenuBase,而MenuBase继承于ItemsControl。所以学习Menu之前,要先了解一下MenuBase基类。它是一个抽象类,拥有一个ItemContainerTemplateSelector模板选择器,并重写了一些关于键盘和鼠标的方法。
Menu的子项必须为MenuItem。这个MenuItem和前面的TreeViewItem类似,拥有共同的HeaderedItemsControl父类,也就是说,MenuItem本身也是一个集合控件,若要以代码形式加载Menu的内容,也必须要掌握递归的加载思路。
1. 示例1
MenuItem从鼠标的交互上,提供了两种方式。第一种是提供了Click事件,开发者可以订阅该事件以编写相应的业务逻辑。第二种是提供了ICommand接口属性和CommandParameter命令参数,以WPF命令的形式开发业务逻辑。
前端代码
csharp
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Menu x:Name="_Menu">
<MenuItem Header="文件">
<MenuItem Header="新建" Click="MenuItem_Click"/>
<MenuItem Header="打开" Click="MenuItem_Click">
<MenuItem.Icon>
<Image Source="/Images/logo.png"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="编辑"/>
<MenuItem Header="视图"/>
<MenuItem Header="项目"/>
<MenuItem Header="调试"/>
<MenuItem Header="测试"/>
<MenuItem Header="分析"/>
<MenuItem Header="工具"/>
<MenuItem Header="帮助"/>
</Menu>
<TextBlock x:Name="_TextBlock" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
后端代码
csharp
using System.Windows;
using MenuItem = System.Windows.Controls.MenuItem;
namespace WpfTest01
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
var item = sender as MenuItem;
_TextBlock.Text = $"你单击了 {item.Header}";
}
}
}
2. Menu数据绑定
我们需要创建一个实体类,来代表Menu的每一个子项。
后端代码
csharp
using System.Collections.Generic;
namespace WpfTest01
{
/// <summary>
/// 主菜单的实体
/// </summary>
public class MenuModel
{
public string Name { get; set; }
public List<MenuModel> Children { get; set; } = new List<MenuModel>();
public string View { get; set; }
}
}
前端代码
csharp
<Window x:Class="WpfTest01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTest01"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Menu x:Name="_Menu">
<Menu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</Menu.ItemTemplate>
</Menu>
</Grid>
</Window>
后端代码
csharp
using System.Collections.Generic;
namespace WpfTest01
{
public partial class MainWindow
{
public List<MenuModel> Menus { get; set; } = new List<MenuModel>();
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
MenuModel parent = new MenuModel();
parent.Name = $"一级菜单 ";
for (int j = 0; j < 5; j++)
{
MenuModel child = new MenuModel();
child.Name = $"二级菜单 ";
parent.Children.Add(child);
}
Menus.Add(parent);
}
_Menu.ItemsSource = Menus;
}
}
}
ContextMenu上下文菜单
ContextMenu上下文菜单必须要依附于一个"宿主控件"。由于FrameworkElement基类有一个叫ContextMenu的属性,代表了鼠标右键时弹出一个菜单,所以大多数控件都可以设置"上下文菜单"。
ContextMenu继承于MenuBase,而MenuBase继承于ItemsControl。所以,ContextMenu本质上也是一个集合控件。而它的元素则是MenuItem。在用法上,与Menu控件差不多。
1. 属性成员
- HorizontalOffset:获取或设置目标原点和弹出项对齐之间的水平距离点。
- StaysOpen:是否保持打开状态。
- CustomPopupPlacementCallback:获取或设置ContextMenu指示在屏幕位置的回调。
- HasDropShadow:是否有投影出现的上下文菜单。
- Placement:获取或设置ContextMenu显示的相对位置。
- PlacementRectangle:获取或设置相对于其上下文菜单位于在打开时的区域。
- PlacementTarget:获取或设置ContextMenu打开时的相对控件。
- IsOpen:是否打开。
- VerticalOffset:获取或设置目标原点和弹出项对齐之间的垂直距离点。
2. ContextMenu示例
csharp
<Window x:Class="WpfTest01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTest01"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Border Background="LightBlue" Width="200" Height="100" CornerRadius="15">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="复制"/>
<MenuItem Header="粘贴"/>
<MenuItem Header="删除"/>
<MenuItem Header="关于"/>
</ContextMenu>
</Border.ContextMenu>
</Border>
</Grid>
</Window>
StatusBar状态栏
StatusBar是一个"包容性"极强的控件,通常的作用是作为程序的状态内容显示。它同样继承于ItemsControl基类,所以,它也是一个集合控件。
它的元素是StatusBarItem类型,而StatusBarItem继承于ContentControl内容控件,所以,本质上讲,StatusBar的元素可以是任意类型的控件。因为StatusBarItem元素有一个叫Content的属性。
这个控件其实并不常用,通常情况下被当成一个布局控件来使用。如下所示:
csharp
<Window x:Class="WpfTest01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTest01"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<StatusBar Grid.Row="1">
<StatusBarItem Content="www.baidu.com"/>
<StatusBarItem>
<CheckBox Content="CheckBox"/>
</StatusBarItem>
<StatusBarItem>
<RadioButton Content="RadioButton"/>
</StatusBarItem>
<StatusBarItem>
<Button Content="Button"/>
</StatusBarItem>
<TextBlock Text="文字块"/>
</StatusBar>
</Grid>
</Window>
到此WPF的常用的集合控件就给大家分享完了,我认为还是非常全面的,每一个控件的详细使用都给大家做了演示和代码分享,希望能够帮助到大家,接下来会继续给大家分享WPF的数据绑定,这个是WPF的灵魂,没有数据的绑定,页面也就没有了意义,就是一个空壳子,希望大家持续关注。