原视频内容
WPF项目实战合集(2022终结版) 24P
其他内容
WPF MaterialDesign 初学项目实战(0):github 项目Demo运行
WPF MaterialDesign 初学项目实战(1)首页搭建
WPF MaterialDesign 初学项目实战(2)首页导航栏样式
WPF MaterialDesign 初学项目实战(3)动态侧边栏
本期内容:
- 添加侧边栏路由
- 路由管理
创建侧边栏页面
注意:这里添加的控件是用户控件:
名称 | 作用 |
---|---|
窗口WPF | 主窗口,窗口WPF上面不能叠加窗口WPF |
页WPF | 没用过,好像是用来写网页的 |
用户控件WPF | 相当于组件,用于在窗口WPF上面叠加的子窗口 |
资源词典WPF | 相当于css样式 |
添加页面:
- MyToDo(项目根路径)
- Views
- IndexView:主页
- MenuVIew:记事本
- ToDOView: 备忘录
- SettingView:设置
- Views
注意是用户控件WPF,打开背景是透明的,效果如下
然后每个文件添加文本,用于区分
<TextBlock Text="Index" FontSize="80"/>//TexT有差异,用于区分页面
添加对应的ViewModel
我们在WPF MaterialDesign 初学项目实战(3)动态侧边栏,里面使用的是prism自动绑定,这里我们使用App.xmal里面的强制绑定
App.xmal
namespace MyToDo
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : PrismApplication
{
/// <summary>
/// 重写运行主窗口
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
protected override Window CreateShell()
{
//重定向主窗口
return Container.Resolve<MainView>();
}
/// <summary>
/// 依赖注入
/// </summary>
/// <param name="containerRegistry"></param>
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
+ containerRegistry.RegisterForNavigation<MainView, MainViewModel>();
+ containerRegistry.RegisterForNavigation<IndexView, IndexViewModel>();
+ containerRegistry.RegisterForNavigation<ToDoView, ToDoViewModel>();
+ containerRegistry.RegisterForNavigation<MenuView, MenuViewModel>();
+ containerRegistry.RegisterForNavigation<SettingView, SettingViewModel>();
}
}
}
最难的一步:绑定按钮事件,跳转路由
在基本页面设置好了之后,我们就要开始尝试跳转路由了
第一步,引入NuGet包
Microsoft.Xaml.Behaviors.Wpf,这个包用于添加按钮事件
引入命名空间:
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
在ManiView里面添加按钮事件
namespace MyToDo.ViewModels
{
public class MainViewModel : BindableBase//继承BindableBase可以动态更新
{
public MainViewModel(IRegionManager regionManager)//引入regionManager路由管理
{
menuBars = new ObservableCollection<MenuBar>();
CreateMenuBar();
NavigateCommand = new DelegateCommand<MenuBar>(Navigate);
this.regionManager = regionManager;
//添加前进后退按钮事件
GoBackBtn = new DelegateCommand(() =>
{
if (journal!=null && journal.CanGoBack)
{
journal.GoBack();
}
});
GoForwardBtn = new DelegateCommand(() =>
{
if (journal != null && journal.CanGoForward)
{
journal.GoForward();
}
});
}
/// <summary>
/// 导航函数
/// </summary>
/// <param name="obj"></param>
private void Navigate(MenuBar obj)
{
//加入判断,如果是空对象或者命名空间为空则跳出
if (obj == null || string.IsNullOrEmpty(obj.NameSpace))
{
return;
}
regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(obj.NameSpace, back =>
{
//使用回调函数,添加路由日志
journal = back.Context.NavigationService.Journal;
});
}
/// <summary>
/// 用于导航
/// </summary>
public DelegateCommand<MenuBar> NavigateCommand { get; set; }
/// <summary>
/// 返回按钮
/// </summary>
public DelegateCommand GoBackBtn { get; set; }
/// <summary>
/// 前进按钮
/// </summary>
public DelegateCommand GoForwardBtn { get; set; }
/// <summary>
/// 引入Prism路由管理
/// </summary>
private readonly IRegionManager regionManager;
/// <summary>
/// Prism导航日志,路由前进或者后退
/// </summary>
private IRegionNavigationJournal journal;
private ObservableCollection<MenuBar> menuBars;
public ObservableCollection<MenuBar> MenuBars
{
get { return menuBars; }
set { menuBars = value; RaisePropertyChanged(); }
} //动态更新列表
void CreateMenuBar()
{
MenuBars.Add(new MenuBar { Icon = "Home", Title = "首页", NameSpace = "IndexView" });
MenuBars.Add(new MenuBar { Icon = "Notebook", Title = "代办事项", NameSpace = "ToDoView" });
MenuBars.Add(new MenuBar { Icon = "NotebookEdit", Title = "备忘录", NameSpace = "MenuView" });
MenuBars.Add(new MenuBar { Icon = "CogOutline", Title = "设置", NameSpace = "SettingView" });
}
}
}
知识补充
- DelegateCommand 是委托事件,相当于定义函数,要在别的地方实例化
- IRegionManager regionManager 是用于路由跳转
- IRegionNavigationJournal journal 用于记录
新建路由管理实体类
虽然我们这里只有一个路由类,但是我们为了以后路由管理的方便,我们这里添加一个新的路由类
- 根目录
- Common
- Prism
- PrismManager
- PrismManager
- Prism
- Common
namespace MyToDo.Common.Prism
{
public static class PrismManager
{
public static readonly string MainViewRegionName = "MainViewRegion";
}
}
添加点击事件
<ListBox ItemsSource="{Binding MenuBars}"
ItemContainerStyle="{StaticResource MyListBoxItemStyle}"
x:Name="menuBar"
>
<!--添加行为-->
<behaviors:Interaction.Triggers>
<!--按钮选择行为-->
<behaviors:EventTrigger EventName="SelectionChanged">
<!--绑定按钮选择功能-->
<behaviors:InvokeCommandAction Command="{Binding NavigateCommand}" CommandParameter="{Binding ElementName=menuBar,Path=SelectedItem}"/>
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center"
Background="Transparent">
<materialDesign:PackIcon Kind="{Binding Icon}"
Margin="15,0" />
<TextBlock Text="{Binding Title}"
Margin="10,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
这里没看懂的多看看原视频教程
实现效果:
点击侧边栏收起侧边栏
添加名称
在MainView里面
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}"
+ x:Name="drawerHost"
>
在MainView.cs里面添加事件
public MainView()
{
InitializeComponent();
......
//点击侧边栏收起事件
menuBar.SelectionChanged += (s, e) =>
{
drawerHost.IsLeftDrawerOpen = false;
};
}
最终效果: