实现导航的前进和后退Button的IsEnable控制【WPF】
以一种很鬼畜的方式实现导航的前进和后退的按钮IsEnable控制,虽然含傻逼,但是也算是一个复习,所以记录下来。
为什么要这样
因为使用的是Prism实现的,开始时想要根据 CanGoBack和CanGoForward 去设置前进和后退两个按钮的状态。
如何发现,IRegionNavigationJournal 内部的CanGoBack和CanGoForward是没办法进行通知属性更新的,悲~。
如何想起了学习到了静态代理模式【本次复习的就是这】
代理 IRegionNavigationJournal
- 在调用GoBack()和GoForward()时,进行通知更新
using CommunityToolkit.Mvvm.ComponentModel;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CommunitySecurity.App.Commons
{
public partial class NavigationJournalProfix : ObservableObject, IRegionNavigationJournal
{
private IRegionNavigationJournal Journal { get; set; }
public bool CanGoBack => Journal.CanGoBack;
public bool CanGoForward => Journal.CanGoForward;
public IRegionNavigationJournalEntry CurrentEntry => Journal.CurrentEntry;
public INavigateAsync NavigationTarget { get => Journal.NavigationTarget; set => Journal.NavigationTarget = value; }
public NavigationJournalProfix(IRegionNavigationJournal Journal)
{
this.Journal = Journal;
}
public void GoBack()
{
Journal.GoBack();
OnPropertyChanged(nameof(CanGoBack));
OnPropertyChanged(nameof(CanGoForward));
}
public void GoForward()
{
Journal.GoForward();
OnPropertyChanged(nameof(CanGoBack));
OnPropertyChanged(nameof(CanGoForward));
}
public void RecordNavigation(IRegionNavigationJournalEntry entry, bool persistInHistory)
{
Journal.RecordNavigation(entry, persistInHistory);
}
public void Clear()
{
Journal.Clear();
}
}
}
ViewModel
using CommunitySecurity.App.Commons;
using CommunitySecurity.App.Commons.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace CommunitySecurity.App.ViewModels
{
public partial class MainWindowViewModel : ObservableObject
{
#region 属性
/// <summary>
/// 获取当前窗口
/// </summary>
private Window CuurentWindow
{ get { return Application.Current.MainWindow; } }
[ObservableProperty]
private ObservableCollection<MenuBar> menuBarList;
[ObservableProperty]
private MenuBar settingMenuBar;
[ObservableProperty]
private MenuBar exitMenuBar;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(NavigateLoggingCommand))]
private NavigationJournalProfix navigationJournal;
private readonly IRegionManager regionManager;
#endregion 属性
#region Command
/// <summary>
/// ListBox 导航命令
/// </summary>
/// <param name="menuBar"></param>
[RelayCommand]
private void Navigate(MenuBar menuBar)
{
if (menuBar == null || string.IsNullOrWhiteSpace(menuBar.NameSpace)) return;
NavigationParameters pairs = new NavigationParameters();
regionManager.Regions["MainContentRegion"].RequestNavigate(menuBar.NameSpace, result =>
{
//成功了,就记录日志
if ((bool)result.Result)
{
NavigationJournal = new NavigationJournalProfix(result.Context.NavigationService.Journal);
}
}, pairs);
}
/// <summary>
/// 导航日志
/// 返回上一步导航,前往下一步导航
/// </summary>
[RelayCommand(CanExecute = nameof(CanExecuteGoBackAndCanGoForward))]
private void NavigateLogging(string obj)
{
if (obj.Equals("Left"))
{
//上一步
NavigationJournal.GoBack();
}
else
{
//下一步
NavigationJournal.GoForward();
}
NavigationJournal = new NavigationJournalProfix(NavigationJournal);
}
private bool CanExecuteGoBackAndCanGoForward(string obj)
{
if (NavigationJournal == null || string.IsNullOrWhiteSpace(obj) || (!"Left".Equals(obj) && !"Right".Equals(obj))) return false;
return "Left".Equals(obj) ? NavigationJournal.CanGoBack : NavigationJournal.CanGoForward;
}
#endregion Command
public MainWindowViewModel(IRegionManager regionManager)
{
DataInit();
this.regionManager = regionManager;
}
#region 初始化
/// <summary>
/// 数据初始化准备
/// </summary>
private void DataInit()
{
//创建左侧菜单
CreateLeftMenuBar();
}
/// <summary>
/// 创建左侧菜单
/// </summary>
private void CreateLeftMenuBar()
{
settingMenuBar = new MenuBar("CogOutline", "设置", "SettingView");
exitMenuBar = new MenuBar("LocationExit", "退出", "");
menuBarList = new ObservableCollection<MenuBar>();
menuBarList.Add(new MenuBar("MonitorEye", "环境监测", "SensorView"));
menuBarList.Add(new MenuBar("VectorLink", "设备控制", "ActuatorView"));
menuBarList.Add(new MenuBar("Security", "安防监控", "SecurityView"));
menuBarList.Add(new MenuBar("Webcam", "视频监控", "MonitorView"));
menuBarList.Add(new MenuBar("Tune", "配置", "ConfigOptionView"));
}
#endregion 初始化
}
}
View
<Window
x:Class="CommunitySecurity.App.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/"
Width="1200"
Height="650"
MaxHeight="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenHeight}}"
AllowsTransparency="True"
Background="Transparent"
FontFamily="{materialDesign:MaterialDesignFont}"
TextElement.FontSize="14"
TextElement.FontWeight="Medium"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
WindowStyle="None">
<Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- 左侧导航栏 -->
<materialDesign:Card
Grid.Column="0"
Padding="0,10,0,10"
HorizontalContentAlignment="Center"
Background="{DynamicResource PrimaryHueLightBrush}"
Foreground="{DynamicResource PrimaryHueDarkForegroundBrush}"
UniformCornerRadius="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Button
Grid.Row="0"
Margin="0,0,0,30"
Background="{DynamicResource MaterialDesignTextFieldBoxBackground}"
Command="{Binding NavigateCommand}"
CommandParameter="{Binding SettingMenuBar}"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="MaterialDesignIconButton">
<materialDesign:PackIcon Foreground="White" Kind="{Binding SettingMenuBar.Icon}" />
</Button>
<ListBox
Grid.Row="1"
Width="70"
VerticalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
materialDesign:HintAssist.Hint="Search"
ItemContainerStyle="{DynamicResource MyListBoxItemStyle}"
ItemsSource="{Binding MenuBarList}">
<!-- 触发器 -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding NavigateCommand}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<!-- 模板 -->
<ListBox.ItemTemplate>
<DataTemplate>
<Button
Width="40"
Height="40"
Margin="0,5"
DockPanel.Dock="Top"
Focusable="False"
IsHitTestVisible="False"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="MaterialDesignIconButton">
<materialDesign:PackIcon Foreground="White" Kind="{Binding Icon}" />
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button
Grid.Row="2"
Margin="0,30,0,0"
Background="{DynamicResource MaterialDesignTextFieldBoxBackground}"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="MaterialDesignIconButton">
<materialDesign:PackIcon Foreground="White" Kind="{Binding ExitMenuBar.Icon}" />
</Button>
</Grid>
</materialDesign:Card>
<!-- 顶部菜单栏 和 主体区域 -->
<Border
Grid.Column="1"
Margin="0,10"
Background="#ffffff" />
<Grid Grid.Column="1" Margin="0,10,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!-- 顶部菜单栏 -->
<materialDesign:ColorZone
Name="TopMenu"
Grid.Row="0"
Height="60"
Background="#38B290"
CornerRadius="2">
<DockPanel>
<!-- 最右区域 -->
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<!-- 头像 -->
<materialDesign:PopupBox>
<!-- 图钉 设置为图片 -->
<materialDesign:PopupBox.ToggleContent>
<Image
Width="40"
Height="40"
Margin="5"
Source="/Source/Images/user.jpeg">
<Image.Clip>
<EllipseGeometry
Center="20,20"
RadiusX="20"
RadiusY="20" />
</Image.Clip>
</Image>
</materialDesign:PopupBox.ToggleContent>
</materialDesign:PopupBox>
<!-- 用户名 -->
<TextBlock
Margin="0,0,10,0"
VerticalAlignment="Center"
FontSize="13"
Foreground="White"
Text="Admin...." />
<Button
Name="winMinBtn"
Height="auto"
Padding="15,0"
Style="{StaticResource MaterialDesignFlatButton}"
ToolTip="MaterialDesignFlatButton">
<materialDesign:PackIcon Foreground="White" Kind="WindowMinimize" />
</Button>
<Button
Name="winMaxBtn"
Height="auto"
Padding="15,0"
Style="{StaticResource MaterialDesignFlatButton}"
ToolTip="MaterialDesignFlatButton">
<materialDesign:PackIcon
Name="maxBtnIcon"
Foreground="White"
Kind="WindowMaximize" />
</Button>
<Button
Name="winCloseBtn"
Height="auto"
Margin="0"
Padding="15,0"
Style="{StaticResource MaterialDesignFlatButton}"
ToolTip="MaterialDesignFlatButton">
<materialDesign:PackIcon Foreground="White" Kind="WindowClose" />
</Button>
</StackPanel>
<!-- 最左区域 -->
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
<materialDesign:PackIcon
Width="40"
Height="30"
Margin="15,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White"
Kind="ShieldHome" />
<TextBlock
VerticalAlignment="Center"
FontSize="19"
Foreground="White"
Text="智慧小区安防系统" />
</StackPanel>
<!-- 导航日志区域 -->
<StackPanel
Margin="60,0,0,0"
VerticalAlignment="Center"
materialDesign:RippleAssist.IsCentered="True"
DockPanel.Dock="Left"
Orientation="Horizontal">
<Button
Width="30"
Height="30"
Margin="0,0,5,0"
Background="{DynamicResource MaterialDesignTextFieldBoxBackground}"
Command="{Binding NavigateLoggingCommand}"
CommandParameter="Left"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="MaterialDesignIconButton">
<materialDesign:PackIcon Foreground="#ffffff" Kind="ChevronLeft" />
</Button>
<Button
Width="30"
Height="30"
Margin="5,0,0,0"
Background="{DynamicResource MaterialDesignTextFieldBoxBackground}"
Command="{Binding NavigateLoggingCommand}"
CommandParameter="Right"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="MaterialDesignIconButton">
<materialDesign:PackIcon Foreground="#ffffff" Kind="ChevronRight" />
</Button>
</StackPanel>
</DockPanel>
</materialDesign:ColorZone>
<!-- 主体区域 -->
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="MainContentRegion" />
</Grid>
</Grid>
</Border>
</Window>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现