前面我们看了SideMenuItem,今天就在此基础上做出完整的侧边栏菜单喽。
支持多开和单开,具体效果看看视频吧。
看看效果吧:
下面就看看代码喽:
先添加一个SideMenu控件类:
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
namespace WPFDemos
{
public class SideMenu : Control
{
public ObservableCollection<SideMenuItemViewModel> MenuItems
{
get { return (ObservableCollection<SideMenuItemViewModel>)GetValue(MenuItemsProperty); }
set { SetValue(MenuItemsProperty, value); }
}
public static readonly DependencyProperty MenuItemsProperty =
DependencyProperty.Register("MenuItems", typeof(ObservableCollection<SideMenuItemViewModel>), typeof(SideMenu), new PropertyMetadata(default(ObservableCollection<SideMenuItemViewModel>)));
public static readonly RoutedEvent MenuItemselectedChangedEvent = EventManager.RegisterRoutedEvent("MenuItemselectedChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SideMenu));
public event RoutedEventHandler MenuItemselectedChanged
{
add { AddHandler(MenuItemselectedChangedEvent, value); }
remove { RemoveHandler(MenuItemselectedChangedEvent, value); }
}
public void OnMenuItemselectedChanged(DependencyObject dependencyObject)
{
RoutedEventArgs args = new RoutedEventArgs()
{
RoutedEvent = MenuItemselectedChangedEvent,
Source = dependencyObject,
};
RaiseEvent(args);
}
}
}
这个类就很简单了,只是定义了选中事件和menuitem的列表集合。
再添加样式:
<Style x:Key="MenuItemstyle1" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="MinHeight" Value="40"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<local:SideMenuItem DataContext="{TemplateBinding DataContext}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:SideMenu">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SideMenu">
<Border Margin="{TemplateBinding Padding}"
Width="{TemplateBinding Width}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<ScrollViewer Padding="0 0 -8 0">
<ListBox
Focusable="False"
Style="{StaticResource ListBoxStyle1}"
ItemsSource="{Binding MenuItems,RelativeSource={RelativeSource TemplatedParent}}"
ItemContainerStyle="{StaticResource MenuItemstyle1}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后定义SideMenuViewModel:
using System.Collections.ObjectModel;
namespace WPFDemos
{
public class SideMenuViewModel : BaseViewModel
{
private ObservableCollection<SideMenuItemViewModel> _menuItemViewModels;
public ObservableCollection<SideMenuItemViewModel> MenuItemViewModels
{
get { return _menuItemViewModels; }
set
{
_menuItemViewModels = value;
OnPropertyChanged(nameof(MenuItemViewModels));
}
}
private bool _supportMultiOpen;
public bool SupportMultiOpen
{
get { return _supportMultiOpen; }
set
{
_supportMultiOpen = value;
OnPropertyChanged(nameof(SupportMultiOpen));
}
}
}
}
最后改一下MainWindow:
<Window x:Class="WPFDemos.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:WPFDemos"
mc:Ignorable="d"
x:Name="widnow"
WindowStartupLocation="CenterScreen"
UseLayoutRounding="True"
Background="LightBlue"
Title="下拉菜单控件" Height="600" Width="1000">
<Grid Background="LightBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<local:SideMenu MenuItems="{Binding Models.MenuItemViewModels}"
Background="#16181d"
HorizontalAlignment="Left"
MenuItemselectedChanged="S"
/>
<StackPanel Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="刚刚点击了" FontSize="30" Margin="10"/>
<TextBlock x:Name="log" HorizontalAlignment="Center" FontSize="30" VerticalAlignment="Bottom" Margin="0 0 0 50"/>
</StackPanel>
</Grid>
</Window>
窗口后台代码定义列表的DataContext:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WPFDemos
{
public partial class MainWindow : Window
{
public SideMenuViewModel Models { get; set; }
public MainWindow()
{
Models = new SideMenuViewModel() { SupportMultiOpen = true };
Models.MenuItemViewModels = new ObservableCollection<SideMenuItemViewModel>
{
new SideMenuItemViewModel()
{
Parent = Models,
HeaderText = "快速开始",
IconGeometry = FindResource("Flag") as Geometry,
Items = new List<object>()
{
"5.0新变化",
"第一个项目",
"第一个模块",
"自定义用户",
"捐赠",
"FAQ"
},
},
new SideMenuItemViewModel()
{
Parent = Models,
HeaderText = "框架配置",
IconGeometry = FindResource("IconInfo") as Geometry,
Items = new List<object>()
{
"Test1",
"Test2",
"Test3",
"Test5",
},
},
new SideMenuItemViewModel()
{
Parent = Models,
HeaderText = "模型层",
IconGeometry = FindResource("IconInfo") as Geometry,
Items = new List<object>()
{
"Test1",
"Test2",
"Test3",
"Test5",
},
},
new SideMenuItemViewModel()
{
Parent = Models,
HeaderText = "视图模型层",
IconGeometry = FindResource("IconInfo") as Geometry,
Items = new List<object>()
{
"Test1",
"Test2",
"Test3",
"Test5",
},
},
new SideMenuItemViewModel()
{
Parent = Models,
HeaderText = "控制器层",
IconGeometry = FindResource("IconInfo") as Geometry,
Items = new List<object>()
{
"Test1",
"Test2",
"Test3",
"Test5",
},
},
};
InitializeComponent();
DataContext = this;
}
private void S(object sender, RoutedEventArgs e)
{
var s = e.OriginalSource as ListBox;
var str = s.SelectedItem;
log.Text = str.ToString();
}
}
}
这就完成 啦。
注意:本次是在昨天的基础上做的修改,详情见公众号历史记录喽~
需要源码的小伙伴,关注公众号WPF UI,回复SideMenu即可获取哦
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容