使用Prism框架搭建Mvvm模式WPF程序
一、使用NuGet安装Prism框架
二、构建ViewModel基类,注册导航器,弹窗服务,事件聚合器,多语言,log4net日志
1、新建ViewModelBase基类,继承自BindableBase, INavigationAware, IRegionMemberLifetime, IConfirmNavigationRequest构建ViewModel的通用方法,其他页面的ViewModel类均继承该基类即可。
1 public abstract class ViewModelBase : BindableBase, INavigationAware, IRegionMemberLifetime, IConfirmNavigationRequest 2 { 3 /// <summary> 4 /// 导航器 5 /// </summary> 6 public IRegionManager Region; 7 /// <summary> 8 /// 弹窗服务 9 /// </summary> 10 public IDialogService Dialog; 11 /// <summary> 12 /// 事件聚合器 13 /// </summary> 14 public IEventAggregator Event; 15 /// <summary> 16 /// 日志 17 /// </summary> 18 public ILogger Logger; 19 20 public ILanguage language; 21 22 public ViewModelBase() 23 { 24 } 25 26 public ViewModelBase(IContainerExtension container) 27 { 28 this.language = container.Resolve<ILanguage>(); 29 this.Region = container.Resolve<IRegionManager>(); 30 this.Dialog = container.Resolve<IDialogService>(); 31 this.Event = container.Resolve<IEventAggregator>(); 32 this.Logger = container.Resolve<ILogger>(); 33 } 34 35 private DelegateCommand _LoadedCommand; 36 public DelegateCommand LoadedCommand => 37 _LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand)); 38 39 /// <summary> 40 ///初始化界面加载 41 /// </summary> 42 public virtual void ExecuteLoadedCommand() 43 { 44 45 } 46 47 /// <summary> 48 /// 标记上一个视图时候被销毁 49 /// </summary> 50 public bool KeepAlive => false; 51 52 public virtual void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback) 53 { 54 continuationCallback(true); 55 } 56 57 /// <summary> 58 /// 导航后的目标视图是否缓存 59 /// </summary> 60 /// <param name="navigationContext"></param> 61 /// <returns></returns> 62 public virtual bool IsNavigationTarget(NavigationContext navigationContext) 63 { 64 return false; 65 } 66 67 /// <summary> 68 /// 导航前 69 /// </summary> 70 /// <param name="navigationContext"></param> 71 public virtual void OnNavigatedFrom(NavigationContext navigationContext) 72 { 73 74 } 75 76 /// <summary> 77 /// 导航后 78 /// </summary> 79 /// <param name="navigationContext"></param> 80 public virtual void OnNavigatedTo(NavigationContext navigationContext) 81 { 82 83 } 84 85 /// <summary> 86 /// 分页一页多少数据 87 /// </summary> 88 public List<int> Limits { get; set; } = new List<int>() 89 { 90 10,20,30,40,50 91 }; 92 93 /// <summary> 94 /// 总数据 95 /// </summary> 96 public int Total { get; set; } 97 }
2、增加多语言服务,在ViewModel基类中注册使用
新增多语言接口ILanguage

1 public interface ILanguage 2 { 3 /// <summary> 4 /// 查找当前字典中翻译文字 5 /// </summary> 6 /// <param name="key"></param> 7 /// <returns></returns> 8 object GetValue(string key); 9 /// <summary> 10 /// 根据Key在当前程序中查找翻译文件 11 /// </summary> 12 /// <param name="key"></param> 13 void LoadResourceKey(string key); 14 /// <summary> 15 /// 根据路径加载翻译文件 16 /// </summary> 17 /// <param name="path"></param> 18 void LoadPath(string path); 19 /// <summary> 20 /// 加载翻译文件 21 /// </summary> 22 /// <param name="languageDictionary"></param> 23 void LoadDictionary(ResourceDictionary languageDictionary); 24 /// <summary> 25 /// 刷新视图翻译效果 26 /// </summary> 27 void Refresh(); 28 }
新增多语言扩展类LanguageExtension,继承MarkupExtension类(using System.Windows.Markup;)封装实现获取多语言信息的静态方法

1 public class LanguageExtension : MarkupExtension 2 { 3 private class LanguageConverter : IMultiValueConverter 4 { 5 public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 6 { 7 if (values.Length != 2 || values[0] == null || !(values[1] is ResourceDictionary)) 8 { 9 return string.Empty; 10 } 11 12 if (values[0].Equals(DependencyProperty.UnsetValue)) 13 { 14 return parameter; 15 } 16 17 string text = values[0].ToString(); 18 ResourceDictionary resourceDictionary = (ResourceDictionary)values[1]; 19 if (!resourceDictionary.Contains(text)) 20 { 21 return text; 22 } 23 24 return resourceDictionary[text]; 25 } 26 27 public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 28 { 29 throw new NotImplementedException(); 30 } 31 } 32 33 private static Action action; 34 35 private object _Key; 36 37 private static ResourceDictionary localSource; 38 39 private static ResourceDictionary source; 40 41 public object Key 42 { 43 get 44 { 45 return _Key; 46 } 47 set 48 { 49 _Key = value; 50 } 51 } 52 53 private static ResourceDictionary Source 54 { 55 get 56 { 57 if (source == null) 58 { 59 source = new ResourceDictionary(); 60 } 61 62 return source; 63 } 64 set 65 { 66 if (source != value) 67 { 68 source = value; 69 Refresh(); 70 } 71 } 72 } 73 74 private static bool IsLoadedLanguage { get; set; } 75 76 public LanguageExtension() 77 { 78 } 79 80 public LanguageExtension(object key) 81 : this() 82 { 83 _Key = key; 84 } 85 86 public static object GetValue(string key) 87 { 88 if (Source != null && Source.Contains(key)) 89 { 90 return Source[key]; 91 } 92 93 return key; 94 } 95 96 public static void LoadResourceKey(string key) 97 { 98 if (Application.Current.TryFindResource(key) is ResourceDictionary languageDictionary) 99 { 100 LoadDictionary(languageDictionary); 101 } 102 else 103 { 104 LoadDictionary(new ResourceDictionary()); 105 } 106 } 107 108 public static void LoadPath(string path) 109 { 110 ResourceDictionary languageDictionary = null; 111 if (File.Exists(path)) 112 { 113 using FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read); 114 languageDictionary = (ResourceDictionary)XamlReader.Load((Stream)stream); 115 } 116 else 117 { 118 languageDictionary = new ResourceDictionary 119 { 120 Source = new Uri(path) 121 }; 122 } 123 124 LoadDictionary(languageDictionary); 125 } 126 127 public static void LoadDictionary(ResourceDictionary languageDictionary) 128 { 129 Source = languageDictionary; 130 } 131 132 public static void Refresh() 133 { 134 lock (Source) 135 { 136 if (action != null) 137 { 138 AddApplicationResourcesLanguage(); 139 action(); 140 } 141 } 142 } 143 144 public override object ProvideValue(IServiceProvider serviceProvider) 145 { 146 //IL_00c2: Unknown result type (might be due to invalid IL or missing references) 147 //IL_00cc: Expected O, but got Unknown 148 //IL_00d4: Unknown result type (might be due to invalid IL or missing references) 149 //IL_00de: Expected O, but got Unknown 150 //IL_0161: Unknown result type (might be due to invalid IL or missing references) 151 //IL_016b: Expected O, but got Unknown 152 //IL_016b: Unknown result type (might be due to invalid IL or missing references) 153 //IL_0175: Expected O, but got Unknown 154 //IL_0210: Unknown result type (might be due to invalid IL or missing references) 155 //IL_021a: Expected O, but got Unknown 156 //IL_021a: Unknown result type (might be due to invalid IL or missing references) 157 //IL_0224: Expected O, but got Unknown 158 if (!(serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget provideValueTarget)) 159 { 160 return this; 161 } 162 163 if (provideValueTarget.TargetObject.GetType().FullName == "System.Windows.SharedDp") 164 { 165 return this; 166 } 167 168 object targetObject2 = provideValueTarget.TargetObject; 169 DependencyObject targetObject = (DependencyObject)((targetObject2 is DependencyObject) ? targetObject2 : null); 170 if (targetObject == null) 171 { 172 return this; 173 } 174 175 targetObject2 = provideValueTarget.TargetProperty; 176 DependencyProperty targetProperty = (DependencyProperty)((targetObject2 is DependencyProperty) ? targetObject2 : null); 177 if (targetProperty == null) 178 { 179 return this; 180 } 181 182 try 183 { 184 Action LanguageEvent = null; 185 LanguageEvent = delegate 186 { 187 BindingOperations.SetBinding(targetObject, targetProperty, CreateBinding(Key)); 188 }; 189 RoutedEventHandler loaded = null; 190 RoutedEventHandler unLoaded = null; 191 loaded = (RoutedEventHandler)delegate (object o, RoutedEventArgs e) 192 { 193 action = (Action)Delegate.Combine(action, LanguageEvent); 194 if (o is FrameworkElement) 195 { 196 (o as FrameworkElement).Loaded -= loaded; 197 (o as FrameworkElement).Loaded += loaded; 198 } 199 200 if (o is FrameworkContentElement) 201 { 202 (o as FrameworkContentElement).Loaded -= loaded; 203 (o as FrameworkContentElement).Loaded += loaded; 204 } 205 }; 206 unLoaded = (RoutedEventHandler)delegate (object o, RoutedEventArgs e) 207 { 208 action = (Action)Delegate.Remove(action, LanguageEvent); 209 if (o is FrameworkElement) 210 { 211 (o as FrameworkElement).Unloaded -= unLoaded; 212 (o as FrameworkElement).Unloaded += unLoaded; 213 } 214 else if (o is FrameworkContentElement) 215 { 216 (o as FrameworkContentElement).Unloaded -= unLoaded; 217 (o as FrameworkContentElement).Unloaded += unLoaded; 218 } 219 }; 220 FrameworkElement element = targetObject as FrameworkElement; 221 if (element != null) 222 { 223 element.Loaded += loaded; 224 element.Unloaded += unLoaded; 225 DependencyPropertyChangedEventHandler elementDataContextChanged = null; 226 elementDataContextChanged = (DependencyPropertyChangedEventHandler)Delegate.Combine((Delegate)(object)elementDataContextChanged, (Delegate)(DependencyPropertyChangedEventHandler)delegate 227 { 228 element.DataContextChanged -= elementDataContextChanged; 229 element.DataContextChanged += elementDataContextChanged; 230 BindingOperations.SetBinding(targetObject, targetProperty, CreateBinding(Key)); 231 }); 232 element.DataContextChanged += elementDataContextChanged; 233 } 234 else 235 { 236 FrameworkContentElement contentElement = targetObject as FrameworkContentElement; 237 if (contentElement != null) 238 { 239 contentElement.Loaded += loaded; 240 contentElement.Unloaded += unLoaded; 241 DependencyPropertyChangedEventHandler contentElementDataContextChanged = null; 242 contentElementDataContextChanged = (DependencyPropertyChangedEventHandler)Delegate.Combine((Delegate)(object)contentElementDataContextChanged, (Delegate)(DependencyPropertyChangedEventHandler)delegate 243 { 244 contentElement.DataContextChanged -= contentElementDataContextChanged; 245 contentElement.DataContextChanged += contentElementDataContextChanged; 246 BindingOperations.SetBinding(targetObject, targetProperty, CreateBinding(Key)); 247 }); 248 contentElement.DataContextChanged += contentElementDataContextChanged; 249 } 250 } 251 252 if (!IsLoadedLanguage) 253 { 254 IsLoadedLanguage = AddApplicationResourcesLanguage(); 255 } 256 257 return CreateBinding(Key).ProvideValue(serviceProvider); 258 } 259 catch (Exception ex) 260 { 261 throw new XamlParseException(ex.Message); 262 } 263 } 264 265 private static bool AddApplicationResourcesLanguage() 266 { 267 try 268 { 269 Window window = Application.Current?.MainWindow; 270 if (window != null && !DesignerProperties.GetIsInDesignMode((DependencyObject)(object)window)) 271 { 272 if (localSource == null) 273 { 274 localSource = source; 275 } 276 277 ResourceDictionary resourceDictionary = Application.Current.Resources?.MergedDictionaries?.Where((ResourceDictionary o) => o.Source == localSource.Source)?.FirstOrDefault(); 278 if (resourceDictionary != null) 279 { 280 Application.Current.Resources?.MergedDictionaries?.Remove(resourceDictionary); 281 } 282 283 Application.Current.Resources?.MergedDictionaries?.Add(Source); 284 localSource = Source; 285 } 286 287 return true; 288 } 289 catch 290 { 291 } 292 293 return false; 294 } 295 296 private MultiBinding CreateBinding(object key) 297 { 298 MultiBinding multiBinding = new MultiBinding(); 299 if (key is Binding binding) 300 { 301 multiBinding.ConverterParameter = binding.Path.Path; 302 multiBinding.Bindings.Add(binding); 303 } 304 else 305 { 306 multiBinding.ConverterParameter = key; 307 multiBinding.Bindings.Add(new Binding 308 { 309 Source = key, 310 Mode = BindingMode.OneWay 311 }); 312 } 313 314 multiBinding.Bindings.Add(new Binding 315 { 316 Source = Source, 317 Mode = BindingMode.OneWay 318 }); 319 multiBinding.Converter = new LanguageConverter(); 320 return multiBinding; 321 } 322 }
新增类Language,实现接口ILanguage,调用扩展类LanguageExtension中的静态方法,实现多语言信息的载入和自动翻译

1 public class Language : ILanguage 2 { 3 4 public object GetValue(string key) => LanguageExtension.GetValue(key); 5 6 public void LoadDictionary(ResourceDictionary languageDictionary) => LanguageExtension.LoadDictionary(languageDictionary); 7 8 public void LoadPath(string path) => LanguageExtension.LoadPath(path); 9 10 public void LoadResourceKey(string key) => LanguageExtension.LoadResourceKey(key); 11 12 public void Refresh() => LanguageExtension.Refresh(); 13 }
3.增加log4net日志服务,在ViewModel基类中注册使用
新增ILogger接口,用来实现接口的注册

1 public interface ILogger 2 { 3 /// <summary> 4 /// 详情 5 /// </summary> 6 /// <param name="message"></param> 7 void Info(string message); 8 9 /// <summary> 10 /// 异常日志 11 /// </summary> 12 /// <param name="exception"></param> 13 void Error(Exception exception); 14 15 /// <summary> 16 /// 警告 17 /// </summary> 18 /// <param name="message"></param> 19 void Warn(string message); 20 21 /// <summary> 22 /// Debug 23 /// </summary> 24 /// <param name="message"></param> 25 void Debug(string message); 26 }
使用NuGet安装log4net日志类库
封装Logger类实现接口ILogger

1 public class Logger : ILogger 2 { 3 public void Debug(string message) 4 { 5 LogManager.GetLogger($"==>").Debug(message); 6 } 7 8 public void Error(Exception exception) 9 { 10 LogManager.GetLogger($"==>").Error(exception); 11 } 12 13 public void Info(string message) 14 { 15 LogManager.GetLogger($"==>").Info(message); 16 } 17 18 public void Warn(string message) 19 { 20 LogManager.GetLogger($"==>").Warn(message); 21 } 22 }
三、增加WPF应用程序
1.修改App.xaml文件,修改页面使用prism:PrismApplication,修改后台代码继承PrismApplication实现配置信息的初始化,自定义接口的注入,页面模块的注入等功能
App.xaml页面文件

1 <prism:PrismApplication 2 x:Class="UIApp.App" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:UIApp" 6 xmlns:prism="http://prismlibrary.com/"> 7 <Application.Resources> 8 <ResourceDictionary> 9 <ResourceDictionary.MergedDictionaries> 10 <ResourceDictionary Source="pack://application:,,,/LayUI.Wpf;component/Themes/Default.xaml" /> 11 </ResourceDictionary.MergedDictionaries> 12 <ResourceDictionary x:Key="zh_CN" Source="pack://siteoforigin:,,,/Languaes/zh_CN.xaml" /> 13 <ResourceDictionary x:Key="en_US" Source="pack://siteoforigin:,,,/Languaes/en_US.xaml" /> 14 </ResourceDictionary> 15 </Application.Resources> 16 </prism:PrismApplication>
后台代码

1 public partial class App : PrismApplication 2 { 3 public App() 4 { 5 //初始化日志配置信息 6 log4net.Config.XmlConfigurator.Configure(); 7 NetworkHelper.Initialization(); 8 } 9 protected override Window CreateShell() 10 { 11 return Container.Resolve<LoginWin>(); 12 } 13 protected override void OnStartup(StartupEventArgs e) 14 { 15 base.OnStartup(e); 16 DispatcherUnhandledException += App_DispatcherUnhandledException; 17 } 18 private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) 19 { 20 LayMessage.Error(e.Exception.Message); 21 var loger = Container.Resolve<ILogger>(); 22 loger.Error(e.Exception); 23 e.Handled = true; 24 } 25 26 protected override void RegisterTypes(IContainerRegistry containerRegistry) 27 { 28 //注入自定义接口 29 30 containerRegistry.RegisterInstance<ILanguage>(new Core.Language.Language()); 31 containerRegistry.RegisterInstance<ILayLanguage>(new LayLanguage()); 32 containerRegistry.RegisterInstance<ILogger>(new Logger()); 33 containerRegistry.RegisterInstance<ILayLogger>(new LayLogger()); 34 containerRegistry.RegisterDialogWindow<DialogWindowBase>(); 35 LayDialog.RegisterDialogWindow<DialogWindowBase>("window"); 36 LayDialog.Register(Container.Resolve<IContainerExtension>()); 37 } 38 protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) 39 { 40 moduleCatalog.AddModule<HomeModule>(); 41 moduleCatalog.AddModule<LayuiFundamentalElementModule>(); 42 moduleCatalog.AddModule<LayuiComponentExampleModule>(); 43 44 moduleCatalog.AddModule<SystemConfigModule>(); 45 46 } 47 }
2.编写LoginWinViewModel继承ViewModelBase基类,实现用户登录用户名密码的校验和跳转主窗口MainWindow

1 public class LoginWinViewModel : ViewModelBase 2 { 3 private readonly IContainerExtension _container; 4 5 private readonly IRegionManager _regionManager; 6 7 public LoginWinViewModel(IContainerExtension container, IRegionManager regionManager) 8 { 9 _container = container; 10 _regionManager = regionManager; 11 LoginCommand = new DelegateCommand(ExcuteLoginCommand); 12 CloseCommand = new DelegateCommand(ExcuteCloseCommand); 13 } 14 15 //登录命令 16 public DelegateCommand LoginCommand { get; set; } 17 18 private void ExcuteLoginCommand() 19 { 20 if(string.IsNullOrWhiteSpace(UserName) || string.IsNullOrWhiteSpace(PassWord)) 21 { 22 LayMessage.Error("请输入用户名和密码!!", "Message"); 23 return; 24 } 25 26 var main = Application.Current.MainWindow; 27 var window = _container.Resolve<MainWindow>(); 28 RegionManager.SetRegionManager(window,_regionManager); 29 window.Show(); 30 main.Close(); 31 } 32 33 //关闭命令 34 public DelegateCommand CloseCommand { get; set; } 35 36 private void ExcuteCloseCommand() 37 { 38 var main = Application.Current.MainWindow; 39 main.Close(); 40 } 41 42 //用户名 43 private string _UserName = ""; 44 public string UserName 45 { 46 get { return _UserName; } 47 set { SetProperty(ref _UserName, value); } 48 } 49 50 //密码 51 private string _PassWord; 52 public string PassWord 53 { 54 get { return _PassWord; } 55 set { SetProperty(ref _PassWord, value); } 56 } 57 }
3.多语言文件en_US.xaml的模板格式,添加节点信息即可

1 <ResourceDictionary 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:sys="clr-namespace:System;assembly=mscorlib"> 5 <sys:String x:Key="Github">Github</sys:String> 6 <sys:String x:Key="Title">Welcome to Layui WPF</sys:String> 7 <sys:String x:Key="BasicElements">Basic Elements</sys:String> 8 <sys:String x:Key="Icon">Icon</sys:String> 9 <sys:String x:Key="Skeleton">Skeleton</sys:String> 10 <sys:String x:Key="Button">Button</sys:String> 11 <sys:String x:Key="Form">Form</sys:String> 12 <sys:String x:Key="Menu">Menu</sys:String> 13 <sys:String x:Key="TabControl">TabControl</sys:String> 14 <sys:String x:Key="ProgressBar">ProgressBar</sys:String> 15 <sys:String x:Key="Panel">Panel</sys:String> 16 <sys:String x:Key="Tag">Tag</sys:String> 17 <sys:String x:Key="Expander">Expander</sys:String> 18 <sys:String x:Key="Transition">Transition</sys:String> 19 <sys:String x:Key="Loading">Loading</sys:String> 20 <sys:String x:Key="GIF">GIF</sys:String> 21 <sys:String x:Key="ScaleImage">ScaleImage</sys:String> 22 <sys:String x:Key="Timeline">Timeline</sys:String> 23 <sys:String x:Key="AuxiliaryElement">AuxiliaryElement</sys:String> 24 <sys:String x:Key="FlowItemsControl">FlowItemsControl</sys:String> 25 <sys:String x:Key="ComponentExamples">ComponentExamples</sys:String> 26 <sys:String x:Key="AnimationCommand">AnimationCommand</sys:String> 27 <sys:String x:Key="ToolTip">ToolTip</sys:String> 28 <sys:String x:Key="Badge">Badge</sys:String> 29 <sys:String x:Key="Ripple">Ripple</sys:String> 30 <sys:String x:Key="PopupBox">PopupBox</sys:String> 31 <sys:String x:Key="Dialog">Dialog</sys:String> 32 <sys:String x:Key="Drawer">Drawer</sys:String> 33 <sys:String x:Key="DateTime">DateTime</sys:String> 34 <sys:String x:Key="DataGrid">DataGrid</sys:String> 35 <sys:String x:Key="Pagination">Pagination</sys:String> 36 <sys:String x:Key="DropDownMenu">Drop-down menu</sys:String> 37 <sys:String x:Key="Upload">File upload</sys:String> 38 <sys:String x:Key="ShuttleGrid">Shuttle Grid</sys:String> 39 <sys:String x:Key="TreeView">TreeView</sys:String> 40 <sys:String x:Key="Cascader">Cascader</sys:String> 41 <sys:String x:Key="TreeSelect">TreeSelect</sys:String> 42 <sys:String x:Key="Slider">Slider</sys:String> 43 <sys:String x:Key="Score">Score</sys:String> 44 <sys:String x:Key="Carousel">Carousel</sys:String> 45 <sys:String x:Key="Message">Message</sys:String> 46 <sys:String x:Key="Notification">Notification</sys:String> 47 <sys:String x:Key="NoticeBar">NoticeBar</sys:String> 48 <sys:String x:Key="Keyboard">Keyboard</sys:String> 49 <sys:String x:Key="Code">Honestly typing code</sys:String> 50 <sys:String x:Key="Announcement">Announcement</sys:String> 51 <sys:String x:Key="Blog">Blog</sys:String> 52 <sys:String x:Key="Videos">Videos</sys:String> 53 <sys:String x:Key="QQ">QQ</sys:String> 54 <sys:String x:Key="Copy">Copy</sys:String> 55 <sys:String x:Key="ReplicatingSuccess">Replicating Success</sys:String> 56 <sys:String x:Key="BasicUsage">Basic usage</sys:String> 57 <sys:String x:Key="Refresh">Refresh</sys:String> 58 <sys:String x:Key="Looking">Looking at mountains is not mountains, looking at water is not water, looking at mountains is still mountains, looking at water is still water</sys:String> 59 <sys:String x:Key="lines">Gorgeous dividing lines</sys:String> 60 <sys:String x:Key="DialogBoxAnnouncement">This is a WPF version of the Layui component library, where you can feel the charm of the WPF version of Layui</sys:String> 61 <sys:String x:Key="ModalPopUpWindow">This is a modal pop-up window</sys:String> 62 <sys:String x:Key="NonModalPopUpWindow">This is a non modal pop-up window</sys:String> 63 </ResourceDictionary>
4.编写MainWindowViewModel,实现主窗体属性和命令的绑定

1 /// <summary> 2 /// 多语言 3 /// </summary> 4 public class Language : BindableBase 5 { 6 private string _Title; 7 public string Title 8 { 9 get { return _Title; } 10 set { SetProperty(ref _Title, value); } 11 } 12 private string _Icon; 13 public string Icon 14 { 15 get { return _Icon; } 16 set { SetProperty(ref _Icon, value); } 17 } 18 private string _Key; 19 public string Key 20 { 21 get { return _Key; } 22 set { SetProperty(ref _Key, value); } 23 } 24 } 25 26 /// <summary> 27 /// 主窗口ViewModel 28 /// </summary> 29 public class MainWindowViewModel : ViewModelBase 30 { 31 private Language _Language; 32 public Language Language 33 { 34 get { return _Language; } 35 set 36 { 37 SetProperty(ref _Language, value); 38 language.LoadResourceKey(Language.Key); 39 } 40 } 41 42 private List<Language> _Languages = new List<Language>() 43 { 44 new Language(){ Title="中文",Icon="Images/Svg/cn.svg",Key="zh_CN" }, 45 new Language(){ Title="英语",Icon="Images/Svg/um.svg",Key="en_US" }, 46 }; 47 public List<Language> Languages 48 { 49 get { return _Languages; } 50 set { SetProperty(ref _Languages, value); } 51 } 52 53 private string _Message = ""; 54 public string Message 55 { 56 get { return _Message; } 57 set { SetProperty(ref _Message, value); } 58 } 59 public MainWindowViewModel(IContainerExtension container) : base(container) 60 { 61 Language = Languages.FirstOrDefault(); 62 } 63 #region 视图属性 64 private bool _Network = true; 65 public bool Network 66 { 67 get { return _Network; } 68 set { SetProperty(ref _Network, value); } 69 } 70 71 /// <summary> 72 /// 标题 73 /// </summary> 74 private string _title = nameof(Title); 75 public string Title 76 { 77 get { return _title; } 78 set { SetProperty(ref _title, value); } 79 } 80 81 /// <summary> 82 /// 窗体状态 83 /// </summary> 84 private WindowState _WindowState; 85 public WindowState WindowState 86 { 87 get { return _WindowState; } 88 set { _WindowState = value; RaisePropertyChanged(); } 89 } 90 91 /// <summary> 92 /// 93 /// </summary> 94 private Thickness _GlassFrameThickness; 95 public Thickness GlassFrameThickness 96 { 97 get { return _GlassFrameThickness; } 98 set { _GlassFrameThickness = value; RaisePropertyChanged(); } 99 } 100 101 #endregion 102 103 104 105 #region 核心方法 106 public override void ExecuteLoadedCommand() 107 { 108 base.ExecuteLoadedCommand(); 109 NetworkHelper.NetworkAvailabilityChanged += Network_NetworkAvailabilityChanged; 110 } 111 private void Network_NetworkAvailabilityChanged(bool isAvailable) 112 { 113 Network = isAvailable; 114 } 115 #endregion 116 117 #region 窗体命令 :跳转GitHub 118 private DelegateCommand<string> _GoBrowser; 119 public DelegateCommand<string> GoBrowser => 120 _GoBrowser ?? (_GoBrowser = new DelegateCommand<string>(ExecuteGoBrowser)); 121 122 void ExecuteGoBrowser(string uri) 123 { 124 Process.Start(new ProcessStartInfo(uri)); 125 } 126 #endregion 127 128 #region 窗体命令:跳转QQ 129 private DelegateCommand _GoQQ; 130 public DelegateCommand GoQQ => 131 _GoQQ ?? (_GoQQ = new DelegateCommand(ExecuteGoQQ)); 132 133 void ExecuteGoQQ() 134 { 135 Process.Start(new ProcessStartInfo("https://qm.qq.com/cgi-bin/qm/qr?k=ewLfhryw080flnV8-Zic4JH3N8IP_aGt&jump_from=webapi&authKey=MVumLNpztW43NPgVMwCzLMTm+T2puC4YN3mjg9eDl6/Fet+Elx+8WYQmRAXISrAF")); 136 } 137 #endregion 138 139 140 }
MainWindow.xaml页面文件的实现
通过代码<ContentControl prismRegions:RegionManager.RegionName="{x:Static Nv:SystemResource.Nav_MainContent}" />实现菜单页面Home.xaml的注入

1 <Window x:Class="UIApp.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:Global="clr-namespace:LayUI.Wpf.Global;assembly=LayUI.Wpf" 7 xmlns:Lay="clr-namespace:LayUI.Wpf.Controls;assembly=LayUI.Wpf" 8 xmlns:Nv="clr-namespace:Core;assembly=Core" 9 xmlns:ex="clr-namespace:LayUI.Wpf.Extensions;assembly=LayUI.Wpf.Extensions" 10 xmlns:local="clr-namespace:UIApp.Views" 11 xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Wpf" 12 xmlns:prismRegions="clr-namespace:Prism.Regions;assembly=Prism.Wpf" 13 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 14 mc:Ignorable="d" 15 d:DesignHeight="600" 16 d:DesignWidth="1080" 17 Title="MainWindow" 18 prism:ViewModelLocator.AutoWireViewModel="True" 19 AllowsTransparency="True" 20 WindowStartupLocation="CenterScreen" 21 WindowStyle="None"> 22 23 <i:Interaction.Triggers> 24 <i:EventTrigger EventName="Loaded"> 25 <i:InvokeCommandAction Command="{Binding LoadedCommand}" /> 26 </i:EventTrigger> 27 </i:Interaction.Triggers> 28 <Grid> 29 <Lay:LayTitleBar 30 Background="{DynamicResource LighCyan}" 31 CornerRadius="4" 32 WindowState="{Binding WindowState, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 33 <!--标题--> 34 <Lay:LayTitleBar.Header> 35 <Border Height="40"> 36 <Grid> 37 <Grid.ColumnDefinitions> 38 <ColumnDefinition /> 39 <ColumnDefinition Width="auto" /> 40 </Grid.ColumnDefinitions> 41 <!--标题列--> 42 <TextBlock 43 Margin="10,0" 44 VerticalAlignment="Center" 45 Foreground="Green" 46 FontSize="18" 47 FontWeight="Heavy" 48 Text="{ex:Language {Binding Title}}" /> 49 50 <!--用户信息,多语言信息,公告信息--> 51 <StackPanel 52 Grid.Column="1" 53 HorizontalAlignment="Right" 54 Orientation="Horizontal" 55 WindowChrome.IsHitTestVisibleInChrome="true"> 56 <!--多语言--> 57 <Lay:LayComboBox 58 Width="90" 59 Padding="0" 60 VerticalContentAlignment="Center" 61 Background="Transparent" 62 BorderThickness="0" 63 Foreground="White" 64 ItemsSource="{Binding Languages}" 65 SelectedItem="{Binding Language, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 66 <Lay:LayComboBox.ItemsPanel> 67 <ItemsPanelTemplate> 68 <StackPanel Margin="0,-4" Background="White" /> 69 </ItemsPanelTemplate> 70 </Lay:LayComboBox.ItemsPanel> 71 <Lay:LayComboBox.ItemTemplate> 72 <DataTemplate> 73 <Grid> 74 <Grid.ColumnDefinitions> 75 <ColumnDefinition Width="auto" /> 76 <ColumnDefinition /> 77 </Grid.ColumnDefinitions> 78 <Lay:LaySVGImage 79 Width="20" 80 Height="15" 81 VerticalAlignment="Center" 82 Source="{Binding Icon}" 83 Stretch="UniformToFill" /> 84 <TextBlock 85 Grid.Column="1" 86 Margin="5,0" 87 VerticalAlignment="Center" 88 FontSize="13" 89 Text="{Binding Title}" /> 90 </Grid> 91 </DataTemplate> 92 </Lay:LayComboBox.ItemTemplate> 93 </Lay:LayComboBox> 94 <Lay:LayBadge 95 Margin="5,10" 96 Background="{DynamicResource Red}" 97 IsDot="True" 98 Value="1"> 99 <ToggleButton 100 x:Name="Title" 101 Content="{ex:Language Key='Announcement'}" 102 Cursor="Hand" 103 Foreground="White"> 104 <ToggleButton.Template> 105 <ControlTemplate TargetType="ToggleButton"> 106 <Grid Background="Transparent"> 107 <ContentPresenter VerticalAlignment="Center" /> 108 </Grid> 109 </ControlTemplate> 110 </ToggleButton.Template> 111 </ToggleButton> 112 </Lay:LayBadge> 113 <Grid VerticalAlignment="Center"> 114 <ToggleButton 115 x:Name="MoreToggleButton" 116 Width="50" 117 Content="" 118 Cursor="Hand" 119 FontFamily="{StaticResource IconFont}" 120 FontSize="20" 121 Foreground="White"> 122 <ToggleButton.ToolTip> 123 <TextBlock FontSize="14" Text="更多" /> 124 </ToggleButton.ToolTip> 125 <ToggleButton.Template> 126 <ControlTemplate TargetType="ToggleButton"> 127 <Grid Background="Transparent"> 128 <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> 129 </Grid> 130 </ControlTemplate> 131 </ToggleButton.Template> 132 <ToggleButton.Style> 133 <Style TargetType="ToggleButton"> 134 <Style.Triggers> 135 <DataTrigger Binding="{Binding ElementName=MorePopup, Path=IsOpen}" Value="true"> 136 <Setter Property="IsEnabled" Value="false" /> 137 </DataTrigger> 138 </Style.Triggers> 139 </Style> 140 </ToggleButton.Style> 141 </ToggleButton> 142 <Popup 143 x:Name="MorePopup" 144 AllowsTransparency="True" 145 IsOpen="{Binding ElementName=MoreToggleButton, Path=IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 146 Placement="Bottom" 147 PlacementTarget="{Binding ElementName=MoreToggleButton}" 148 PopupAnimation="Slide" 149 StaysOpen="False" 150 VerticalOffset="5"> 151 <Popup.Style> 152 <Style TargetType="Popup"> 153 <Setter Property="IsOpen" Value="false" /> 154 <Style.Triggers> 155 <DataTrigger Binding="{Binding ElementName=MoreToggleButton, Path=IsChecked}" Value="true"> 156 <Setter Property="IsOpen" Value="true" /> 157 </DataTrigger> 158 </Style.Triggers> 159 </Style> 160 </Popup.Style> 161 <Grid> 162 <Grid.Effect> 163 <DropShadowEffect Opacity="0.5" ShadowDepth="0" /> 164 </Grid.Effect> 165 <Grid 166 Width="10" 167 Height="10" 168 Margin="20,2" 169 HorizontalAlignment="Left" 170 VerticalAlignment="Top" 171 Background="White" 172 RenderTransformOrigin="0.5,0.5"> 173 <Grid.RenderTransform> 174 <TransformGroup> 175 <ScaleTransform /> 176 <SkewTransform /> 177 <RotateTransform Angle="45" /> 178 <TranslateTransform /> 179 </TransformGroup> 180 </Grid.RenderTransform> 181 </Grid> 182 <Border 183 Width="150" 184 Height="auto" 185 Margin="5" 186 Background="White" 187 CornerRadius="{DynamicResource ControlCornerRadiusBase}"> 188 <StackPanel> 189 <StackPanel.Resources> 190 <Style TargetType="Button"> 191 <Setter Property="Width" Value="50" /> 192 <Setter Property="Height" Value="50" /> 193 <Setter Property="Background" Value="Transparent" /> 194 <Setter Property="Cursor" Value="Hand" /> 195 <Setter Property="Template"> 196 <Setter.Value> 197 <ControlTemplate TargetType="Button"> 198 <Border Background="{TemplateBinding Background}"> 199 <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> 200 </Border> 201 </ControlTemplate> 202 </Setter.Value> 203 </Setter> 204 </Style> 205 <Style x:Key="WindowCheckBoxStyle" TargetType="CheckBox"> 206 <Setter Property="Width" Value="50" /> 207 <Setter Property="Height" Value="50" /> 208 <Setter Property="Template"> 209 <Setter.Value> 210 <ControlTemplate TargetType="CheckBox"> 211 <Border Background="Transparent"> 212 <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> 213 </Border> 214 </ControlTemplate> 215 </Setter.Value> 216 </Setter> 217 </Style> 218 </StackPanel.Resources> 219 <Button 220 Width="150" 221 Height="40" 222 HorizontalContentAlignment="Stretch" 223 Command="{Binding GoBrowser}" 224 CommandParameter="https://github.com/Layui-WPF-Team/Layui-WPF"> 225 <Grid Margin="30,0"> 226 <Grid.ColumnDefinitions> 227 <ColumnDefinition Width="auto" /> 228 <ColumnDefinition /> 229 </Grid.ColumnDefinitions> 230 <TextBlock 231 VerticalAlignment="Center" 232 FontFamily="{DynamicResource IconFont-FontAwesome}" 233 FontSize="18" 234 Text="" /> 235 <TextBlock 236 Grid.Column="1" 237 Margin="10,0" 238 HorizontalAlignment="Center" 239 VerticalAlignment="Center" 240 Text="GitHub" /> 241 </Grid> 242 </Button> 243 <Button 244 Width="150" 245 Height="40" 246 HorizontalContentAlignment="Stretch" 247 Command="{Binding GoBrowser}" 248 CommandParameter="https://www.cnblogs.com/ShyFrog/"> 249 <Grid Margin="30,0"> 250 <Grid.ColumnDefinitions> 251 <ColumnDefinition Width="auto" /> 252 <ColumnDefinition /> 253 </Grid.ColumnDefinitions> 254 <TextBlock 255 VerticalAlignment="Center" 256 FontFamily="{DynamicResource IconFont-FontAwesome}" 257 FontSize="18" 258 Text="" /> 259 <TextBlock 260 Grid.Column="1" 261 Margin="10,0" 262 HorizontalAlignment="Center" 263 VerticalAlignment="Center" 264 Text="{ex:Language Key='Blog'}" /> 265 </Grid> 266 </Button> 267 <Button 268 Width="150" 269 Height="40" 270 HorizontalContentAlignment="Stretch" 271 Command="{Binding GoBrowser}" 272 CommandParameter="https://b23.tv/F9IA5Vs"> 273 <Grid Margin="30,0"> 274 <Grid.ColumnDefinitions> 275 <ColumnDefinition Width="auto" /> 276 <ColumnDefinition /> 277 </Grid.ColumnDefinitions> 278 <TextBlock 279 VerticalAlignment="Center" 280 FontFamily="{DynamicResource IconFont-FontAwesome}" 281 FontSize="18" 282 Text="" /> 283 <TextBlock 284 Grid.Column="1" 285 Margin="10,0" 286 HorizontalAlignment="Center" 287 VerticalAlignment="Center" 288 Text="{ex:Language Key='Videos'}" /> 289 </Grid> 290 </Button> 291 <Button 292 Width="150" 293 Height="40" 294 HorizontalContentAlignment="Stretch" 295 Command="{Binding GoQQ}"> 296 <Grid Margin="30,0"> 297 <Grid.ColumnDefinitions> 298 <ColumnDefinition Width="auto" /> 299 <ColumnDefinition /> 300 </Grid.ColumnDefinitions> 301 <TextBlock 302 VerticalAlignment="Center" 303 FontFamily="{DynamicResource IconFont-FontAwesome}" 304 FontSize="18" 305 Text="" /> 306 <TextBlock 307 Grid.Column="1" 308 Margin="10,0" 309 HorizontalAlignment="Center" 310 VerticalAlignment="Center" 311 Text="{ex:Language Key='QQ'}" /> 312 </Grid> 313 </Button> 314 </StackPanel> 315 </Border> 316 </Grid> 317 </Popup> 318 </Grid> 319 </StackPanel> 320 </Grid> 321 </Border> 322 </Lay:LayTitleBar.Header> 323 <!--内容Content--> 324 <Border BorderBrush="{DynamicResource Orange}" BorderThickness="0,1,0,0"> 325 <Grid Cursor=""> 326 <Grid.RowDefinitions> 327 <RowDefinition /> 328 <RowDefinition Height="auto" /> 329 </Grid.RowDefinitions> 330 <Lay:LayDrawerHost DrawerOpen="{Binding ElementName=Title, Path=IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Type="Right"> 331 <Lay:LayDrawerHost.DrawerContent> 332 <Border Width="300" Background="#F7F9F6"> 333 <StackPanel> 334 <Image Source="/LayuiApp;component/R-C.jpg" /> 335 <TextBlock 336 Margin="10" 337 HorizontalAlignment="Center" 338 FontSize="25" 339 Text="{ex:Language Key='Code'}" 340 TextAlignment="Center" 341 TextWrapping="Wrap" /> 342 </StackPanel> 343 </Border> 344 </Lay:LayDrawerHost.DrawerContent> 345 <Grid> 346 <Grid.RowDefinitions> 347 <RowDefinition Height="auto" /> 348 <RowDefinition /> 349 </Grid.RowDefinitions> 350 351 <Border 352 Grid.Row="1" 353 Panel.ZIndex="0" 354 Background="White"> 355 <Grid> 356 <Grid Background="White"> 357 <Grid.Style> 358 <Style TargetType="Grid"> 359 <Setter Property="Panel.ZIndex" Value="100" /> 360 <Setter Property="Visibility" Value="Collapsed" /> 361 <Style.Triggers> 362 <DataTrigger Binding="{Binding Network}" Value="false"> 363 <Setter Property="Visibility" Value="Hidden" /> 364 </DataTrigger> 365 </Style.Triggers> 366 </Style> 367 </Grid.Style> 368 <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 369 <Viewbox Width="150" Height="150"> 370 <Grid Width="1024" Height="1024"> 371 <Path Data="M892.171556 133.778866 131.931798 133.778866c-30.352285 0-55.038524 24.686239-55.038524 55.038524l0 523.098779c0 30.326702 24.711821 55.038524 55.038524 55.038524l41.351803 0c2.5071 7.730055 7.094582 15.376199 13.980409 22.521946 1.685385 1.741667 3.848655 3.007497 6.197142 3.638877 68.938092 17.854647 86.052888 40.059368 90.113367 51.692313 4.508687 12.894681-2.954285 23.260773-3.427052 23.893176-4.432962 5.724375-3.430122 13.923104 2.215458 18.406209 5.720282 4.562922 13.976316 3.614317 18.540262-2.134617 6.250354-7.91118 14.925944-26.927279 7.80578-48.233538-9.785877-29.170366-45.043892-52.113915-104.780415-68.147076-4.955872-5.907547-6.460132-10.759041-6.460132-14.716166l0-0.079818c0.024559-5.273097 3.351328-10.57587 9.335622-15.164375 0.187265-0.13303 0.396019-0.26299 0.554632-0.397043 1.714038-1.26583 3.638877-2.477424 5.749958-3.584642 0.50142-0.292666 1.00284-0.527003 1.50426-0.76441 2.52859-1.266853 5.431709-2.24411 8.3072-3.27151 4.587482-1.108241 12.869099-2.582825 26.027793-2.582825 23.077601 0 50.003857 4.53427 79.988776 13.370519 5.010107 2.185782 10.020214 4.454452 15.084557 7.144724 1.528819 0.818645 3.058662 1.688455 4.588505 2.582825 6.355755 3.564175 12.710486 7.467065 19.120476 11.871375 0.554632 0.39295 1.082658 0.656963 1.633197 1.052982 100.847849 70.809719 89.587388 106.543571 89.667206 106.543571l0 0c-3.40147 6.435573-0.949628 14.427594 5.485945 17.830087 1.952468 1.027399 4.061502 1.528819 6.147 1.528819 4.746094 0 9.31004-2.557242 11.654434-7.04137 4.140297-7.834432 17.933441-47.338145-65.719794-115.986641l233.343489 0c-83.678818 68.673056-69.914326 108.180861-65.774029 115.986641 2.427282 4.562922 7.199982 7.30436 12.105712 7.30436 1.980097 0 4.010337-0.472767 5.907547-1.474584 6.435573-3.40147 9.071609-11.023054 5.67014-17.458627-0.134053-0.342808-11.971659-36.080753 89.37761-107.232257 7.065929-4.955872 14.081717-9.230222 21.096481-13.132088 1.266853-0.711198 2.558265-1.451048 3.824095-2.13564 5.273097-2.794649 10.471492-5.16872 15.690354-7.437389 29.880541-8.783037 56.756655-13.317307 79.780021-13.317307 13.183254 0 21.439288 1.500167 25.974581 2.557242 2.90312 1.027399 5.882987 2.030239 8.385994 3.322675 0.50142 0.23843 0.951675 0.475837 1.424442 0.685615 2.214435 1.187035 4.298909 2.452865 6.067182 3.824095l0.23843 0.158612c6.03853 4.587482 9.359158 9.915837 9.388834 15.217586 0 0.079818 0.050142 0.12996 0.050142 0.209778-0.050142 3.90596-1.608637 8.732895-6.484691 14.586207-59.761082 16.034185-94.993514 38.977733-104.780415 68.147076-7.144724 21.306258 1.555425 40.322357 7.80578 48.233538 4.53734 5.748934 12.818957 6.671956 18.514679 2.134617 5.724375-4.508687 6.67298-12.790304 2.13564-18.511609-0.079818-0.104377-7.831362-10.44591-3.456728-23.470551 3.90289-11.711739 20.863167-34.050514 90.222861-52.034097 2.373047-0.606821 4.507664-1.87265 6.196119-3.6399 6.91141-7.173376 11.524474-14.874779 14.005992-22.654976 29.773094-0.656963 53.798277-24.974811 53.798277-54.905494L947.106726 188.818413C947.18552 158.465105 922.499281 133.778866 892.171556 133.778866L892.171556 133.778866zM216.906122 386.824069l117.357871 0c4.955872 17.433044 13.421684 61.737086-6.435573 117.671003l-1.424442 3.90596c-9.627265 26.767644-21.598924 60.075237 5.010107 128.906905 16.270569 42.010813 6.250354 65.931618-0.581238 76.110445 0-0.024559-0.025583-0.024559-0.051165-0.024559-1.187035-0.476861-2.348488-0.898463-3.50994-1.345648-15.743566-5.934153-30.933523-9.677407-45.306882-11.632945-1.24127-0.155543-2.478448-0.342808-3.718695-0.497327-6.752798-0.76441-13.291724-1.187035-19.621896-1.215688-1.421372 0-2.795673 0.079818-4.217045 0.13303-5.247514 0.12996-10.341532 0.50142-15.193027 1.108241-1.290389 0.158612-2.611477 0.26299-3.877307 0.447185-1.027399 0.158612-1.977028 0.421602-2.979868 0.581238 4.588505-21.836331 7.701402-54.115502-6.671956-75.714426-15.401782-23.261797-18.987447-94.889137-0.26299-148.98008C233.465263 452.966489 223.763296 410.875858 216.906122 386.824069L216.906122 386.824069zM735.228107 637.308961c26.637684-68.882833 14.611789-102.193497 4.958942-128.986723l-1.370207-3.826142c-19.860327-55.959499-11.365862-100.238982-6.40999-117.671003l117.357871 0c-6.881734 24.051789-16.588817 66.141396-8.515954 89.453335 18.669198 54.145178 15.109116 125.797078-0.264013 148.951427-14.402011 21.627577-11.289114 53.881165-6.700609 75.743078-1.028423-0.209778-1.977028-0.447185-3.03001-0.581238-0.844228-0.12996-1.741667-0.184195-2.64013-0.317225-5.457292-0.735757-11.207249-1.131777-17.165961-1.26583-0.793062-0.024559-1.557472-0.075725-2.348488-0.075725-22.046109-0.10847-46.995337 4.270257-73.261561 14.687514C728.980823 703.291744 718.956515 679.348426 735.228107 637.308961L735.228107 637.308961zM920.81185 711.916169c0 15.427364-12.234649 28.007891-27.504424 28.613688-1.76725-5.064342-4.562922-9.970072-8.465812-14.529925-0.554632-0.60989-1.214664-1.186012-1.76725-1.76725-0.212848-0.237407-0.450255-0.421602-0.63445-0.63445-1.951445-2.001587-4.140297-3.90289-6.53995-5.720282-0.73985-0.581238-1.528819-1.161453-2.319835-1.717108-1.87572-1.316995-3.90596-2.557242-6.0416-3.743254-0.89437-0.527003-1.658779-1.1328-2.611477-1.63422-0.288572-0.158612-0.656963-0.23843-0.948605-0.397043-0.025583-0.024559-0.051165-0.024559-0.079818-0.050142-5.010107-16.881482-12.44852-53.276391-0.923022-70.520123 21.940708-33.097816 23.444968-113.534799 3.217275-172.187641-5.457292-15.798824 3.03308-54.642504 11.102872-80.833003l5.167696 0c7.278777 0 13.18837-5.9055 13.18837-13.184277 0-7.277754-5.90857-13.187347-13.18837-13.187347l-14.791891 0L722.939223 360.423793l-11.390421 0c-7.278777 0-13.18837 5.90857-13.18837 13.187347 0 5.115508 2.979868 9.414417 7.225565 11.604292-5.934153 23.496134-12.289907 69.88465 8.360412 128.062678l1.424442 3.982708c8.595772 23.817452 18.327414 50.818409-4.746094 110.474091-18.724457 48.340985-8.91402 79.855746 1.052982 96.736205-8.779967 4.638647-17.667382 9.965979-26.583448 16.033162l-0.024559 0.025583L381.759727 740.529857c-0.844228-0.581238-1.688455-0.974188-2.557242-1.555425-7.229658-4.851495-14.4542-9.205663-21.603017-13.08297-0.868787-0.471744-1.738597-1.052982-2.636037-1.528819 9.970072-16.902972 19.754926-48.391127 1.056052-96.653317-23.077601-59.551304-13.345959-86.527702-4.800329-110.369713l1.450025-4.03285c20.650319-58.181097 14.294564-104.541985 8.361435-128.041188 4.270257-2.189875 7.253194-6.485715 7.253194-11.604292 0-7.278777-5.907547-13.187347-13.187347-13.187347l-11.364839 0L198.99724 360.473935l-14.795984 0c-7.278777 0-13.183254 5.907547-13.183254 13.187347 0 7.278777 5.904477 13.187347 13.183254 13.187347l5.16872 0c8.043187 26.187429 16.563234 65.034179 11.105942 80.833003-19.913539 57.571207-18.384719 139.616828 3.217275 172.183548 11.417027 17.169031 4.03285 53.643758-0.951675 70.520123-0.314155 0.184195-0.735757 0.292666-1.054005 0.451278-1.056052 0.551562-1.90028 1.211595-2.874467 1.76418-1.976004 1.13587-3.877307 2.26867-5.644557 3.50994-0.86981 0.605797-1.714038 1.236154-2.558265 1.871627-2.293229 1.76725-4.403287 3.614317-6.30152 5.564739-0.26299 0.26299-0.554632 0.527003-0.818645 0.789992-0.554632 0.554632-1.211595 1.107217-1.713015 1.688455-1.608637 1.871627-2.874467 3.848655-4.140297 5.8001-0.025583 0.079818-0.079818 0.134053-0.134053 0.187265-1.738597 2.795673-3.217275 5.67014-4.245697 8.595772l-41.35078 0c-15.824407 0-28.668946-12.844539-28.668946-28.664853L103.237269 188.818413c0-15.797801 12.870122-28.667923 28.668946-28.667923l760.239757 0c15.794731 0 28.639271 12.869099 28.639271 28.667923l0 523.098779L920.81185 711.917192zM920.81185 711.916169" Fill="{DynamicResource Green}" /> 372 <Path Data="M484.137419 325.401138c0-7.278777-5.907547-13.18837-13.187347-13.18837-44.701085 0-82.59616-27.636431-100.82329-40.928155-4.191462-3.058662-7.487531-5.432733-9.756201-6.777357-6.275937-3.718695-14.344706-1.662873-18.063401 4.617158-3.719718 6.247284-1.662873 14.344706 4.587482 18.064424 1.76725 1.082658 4.379751 2.978844 7.701402 5.432733 20.466124 14.925944 63.057151 45.992497 116.355031 45.992497C478.229872 338.588485 484.137419 332.679915 484.137419 325.401138L484.137419 325.401138zM484.137419 325.401138" Fill="{DynamicResource Green}" /> 373 <Path Data="M673.097048 264.507256c-2.24411 1.345648-5.565762 3.719718-9.785877 6.777357-18.197454 13.266142-56.092529 40.903595-100.793614 40.903595-7.278777 0-13.187347 5.907547-13.187347 13.187347 0 7.278777 5.907547 13.187347 13.187347 13.187347 53.296857 0 95.888907-31.041994 116.355031-45.966914 3.322675-2.427282 5.934153-4.378727 7.725962-5.432733 6.251378-3.718695 8.3072-11.816117 4.588505-18.067494C687.441754 262.819824 679.345356 260.764002 673.097048 264.507256L673.097048 264.507256zM673.097048 264.507256" Fill="{DynamicResource Green}" /> 374 <Path Data="M606.187149 622.85476l-88.742137-39.820937c-3.6399-1.633197-7.806803-1.528819-11.365862 0.26299l-78.484515 39.825031c-6.514367 3.294023-9.097192 11.231809-5.8001 17.747199 3.267417 6.488785 11.206226 9.021467 17.720593 5.803169l72.864518-36.975123 82.968643 37.238113c1.741667 0.789992 3.614317 1.158383 5.406127 1.158383 5.010107 0 9.837042-2.870374 12.025894-7.777127C615.814414 633.66906 612.834546 625.863281 606.187149 622.85476L606.187149 622.85476zM606.187149 622.85476" Fill="{DynamicResource Green}" /> 375 </Grid> 376 </Viewbox> 377 <TextBlock 378 HorizontalAlignment="Center" 379 FontSize="25" 380 Foreground="{DynamicResource Green}" 381 Text="网络已断开" /> 382 </StackPanel> 383 </Grid> 384 <ContentControl prismRegions:RegionManager.RegionName="{x:Static Nv:SystemResource.Nav_MainContent}" /> 385 </Grid> 386 </Border> 387 </Grid> 388 </Lay:LayDrawerHost> 389 <Lay:LayNoticeBar 390 Grid.Row="1" 391 Height="35" 392 Padding="10,0" 393 BorderBrush="{DynamicResource Black}" 394 BorderThickness="0,1,0,0" 395 Foreground="White" 396 Duration="60"> 397 <Lay:LayNoticeBar.Resources> 398 <Storyboard 399 x:Key="Storyboard" 400 AutoReverse="True" 401 RepeatBehavior="Forever"> 402 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Icon" Storyboard.TargetProperty="(UIElement.Opacity)"> 403 <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.5" /> 404 </DoubleAnimationUsingKeyFrames> 405 </Storyboard> 406 </Lay:LayNoticeBar.Resources> 407 <Lay:LayNoticeBar.Triggers> 408 <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 409 <BeginStoryboard Storyboard="{StaticResource Storyboard}" /> 410 </EventTrigger> 411 </Lay:LayNoticeBar.Triggers> 412 <Lay:LayButton 413 Width="auto" 414 Height="auto" 415 Background="Transparent" 416 Content="{Binding Message}" 417 HoverBackground="Transparent" 418 Type="Customize" 419 Uri="https://github.com/Layui-WPF-Team/Layui-WPF" /> 420 <Lay:LayNoticeBar.InnerLeftContent> 421 <TextBlock 422 x:Name="Icon" 423 VerticalAlignment="Center" 424 FontFamily="{DynamicResource IconFont}" 425 FontSize="20" 426 Text="" /> 427 </Lay:LayNoticeBar.InnerLeftContent> 428 </Lay:LayNoticeBar> 429 <Lay:LayDialogHost 430 Grid.RowSpan="2" 431 Panel.ZIndex="99" 432 Global:LayDialog.Token="RootDialogToken" /> 433 <Lay:LayMessageHost 434 Grid.RowSpan="2" 435 Panel.ZIndex="99" 436 Global:LayMessage.Token="RootMessageToken" /> 437 </Grid> 438 </Border> 439 </Lay:LayTitleBar> 440 </Grid> 441 </Window>
四、增加Home项目,封装实现主窗口的菜单页面
1.编写类HomeModule,实现首页模块注册。将Home页面注入到SystemResource.Nav_MainContent中

1 public class HomeModule : IModule 2 { 3 public void OnInitialized(IContainerProvider containerProvider) 4 { 5 var regionManager = containerProvider.Resolve<IRegionManager>(); 6 7 regionManager.RegisterViewWithRegion(SystemResource.Nav_MainContent, typeof(Home.Views.Home)); 8 } 9 10 public void RegisterTypes(IContainerRegistry containerRegistry) 11 { 12 13 } 14 }
2.编写菜单栏模型类MenuItemModel,为实现数据的双向绑定,继承Prism中的基类BindableBase

1 /// <summary> 2 /// 菜单栏模型 3 /// </summary> 4 public class MenuItemModel : BindableBase 5 { 6 /// <summary> 7 /// 是否选中 8 /// </summary> 9 private bool _IsSelected; 10 public bool IsSelected 11 { 12 get { return _IsSelected; } 13 set { _IsSelected = value; RaisePropertyChanged(); } 14 } 15 16 /// <summary> 17 /// 导航地址 18 /// </summary> 19 private string _PageKey; 20 public string PageKey 21 { 22 get { return _PageKey; } 23 set { _PageKey = value; RaisePropertyChanged(); } 24 } 25 26 /// <summary> 27 /// 标题 28 /// </summary> 29 private string _ItemTitle; 30 public string ItemTitle 31 { 32 get { return _ItemTitle; } 33 set { _ItemTitle = value; RaisePropertyChanged(); } 34 } 35 36 /// <summary> 37 /// 字体图标 38 /// </summary> 39 private string _StringIocn; 40 public string StringIocn 41 { 42 get { return _StringIocn; } 43 set { _StringIocn = value; RaisePropertyChanged(); } 44 } 45 46 /// <summary> 47 /// 多级菜单集合 48 /// </summary> 49 private ObservableCollection<MenuItemModel> _Data; 50 public ObservableCollection<MenuItemModel> Data 51 { 52 get { return _Data; } 53 set { _Data = value; RaisePropertyChanged(); } 54 } 55 56 private bool _IsNew; 57 public bool IsNew 58 { 59 get { return _IsNew; } 60 set { SetProperty(ref _IsNew, value); } 61 } 62 }
3.编写菜单栏模板选择器MenuItemDataTemplateSelector,继承DataTemplateSelector(using System.Windows.Controls;)

1 /// <summary> 2 /// 菜单栏模板选择器 3 /// </summary> 4 public class MenuItemDataTemplateSelector : DataTemplateSelector 5 { 6 public override DataTemplate SelectTemplate(object item, DependencyObject container) 7 { 8 if (item != null) 9 { 10 var fe = container as FrameworkElement; 11 MenuItemModel menuItem = item as MenuItemModel; 12 if (menuItem.Data != null) 13 { 14 15 return fe.FindResource("MenuItemsDataTemplate") as DataTemplate; 16 } 17 else 18 { 19 return fe.FindResource("MenuItemDataTemplate") as DataTemplate; 20 } 21 } 22 return null; 23 } 24 }
4.编写HomeViewModel类继承基类ViewModelBase,实现ViewModel和页面Home.xaml的绑定和命令实现

1 public class HomeViewModel : ViewModelBase 2 { 3 private AnimationType _AnimationType = AnimationType.RotateOut; 4 public AnimationType AnimationType 5 { 6 get { return _AnimationType; } 7 set { SetProperty(ref _AnimationType, value); } 8 } 9 public HomeViewModel(IContainerExtension container) : base(container) 10 { 11 ExecuteLoadedCommand(); 12 } 13 #region 视图属性 14 private bool _Network; 15 public bool Network 16 { 17 get { return _Network; } 18 set { SetProperty(ref _Network, value); } 19 } 20 private MenuItemModel _MenuItemModel; 21 public MenuItemModel MenuItemModel 22 { 23 get { return _MenuItemModel; } 24 set 25 { 26 SetProperty(ref _MenuItemModel, value); 27 new Action(async () => 28 { 29 AnimationType = AnimationType.SlideOutToLeft; 30 await Task.Delay(300); 31 Region.RequestNavigate(SystemResource.Nav_HomeContent, MenuItemModel.PageKey); 32 AnimationType = AnimationType.SlideInToRight; 33 }).Invoke(); 34 } 35 } 36 private ObservableCollection<MenuItemModel> _MenuItemList; 37 /// <summary> 38 /// 导航目录 39 /// </summary> 40 public ObservableCollection<MenuItemModel> MenuItemList 41 { 42 get { return _MenuItemList; } 43 set { _MenuItemList = value; RaisePropertyChanged(); } 44 } 45 #endregion 46 #region 命令 47 /// <summary> 48 /// 导航界面 49 /// </summary> 50 private DelegateCommand<MenuItemModel> _GoPageCommand; 51 public DelegateCommand<MenuItemModel> GoPageCommand => 52 _GoPageCommand ?? (_GoPageCommand = new DelegateCommand<MenuItemModel>(GoPage)); 53 54 #endregion 55 56 #region 核心方法 57 /// <summary> 58 /// 跳转界面 59 /// </summary> 60 /// <param name="PageKey"></param> 61 private void GoPage(MenuItemModel item) 62 { 63 if (item == null) return; 64 MenuItemModel = item; 65 } 66 #endregion 67 public async override void ExecuteLoadedCommand() 68 { 69 //IsAvailable = NetworkHelper.GetLocalNetworkStatus(); 70 //NetworkHelper.NetworkAvailabilityChanged += Network_NetworkAvailabilityChanged; 71 MenuItemList = await GetData(); 72 MenuItemModel = MenuItemList.First().Data.First(); 73 MenuItemList.First().IsSelected = true; 74 MenuItemModel.IsSelected = true; 75 //LayMessage.Success("欢迎使用Layui—WPF组件库", "RootMessageTooken"); 76 } 77 78 bool IsAvailable = false; 79 private void Network_NetworkAvailabilityChanged(bool isAvailable) 80 { 81 Network = isAvailable; 82 if (!IsAvailable && Network == true) 83 { 84 Application.Current.Dispatcher.BeginInvoke(new Action(async () => 85 { 86 MenuItemList = await GetData(); 87 MenuItemModel = MenuItemList.First().Data.First(); 88 MenuItemList.First().IsSelected = true; 89 MenuItemModel.IsSelected = true; 90 LayMessage.Success("网络已恢复", "RootMessageTooken"); 91 LayMessage.Success("程序已重新加载", "RootMessageTooken"); 92 })); 93 } 94 IsAvailable = Network; 95 } 96 private Task<ObservableCollection<MenuItemModel>> GetData() 97 { 98 var list = new ObservableCollection<MenuItemModel>(); 99 100 #region 数据库读取菜单 101 for(var i = 0; i < 10; i++) 102 { 103 list.Add(new MenuItemModel() 104 { 105 ItemTitle = "菜单" + i.ToString(), 106 Data = new ObservableCollection<MenuItemModel>() 107 { 108 new MenuItemModel() 109 { 110 ItemTitle="用户管理", PageKey="SysUserInfos",IsNew=false 111 } 112 } 113 }); 114 } 115 #endregion 116 117 //增加示例页面 118 list.Add(new MenuItemModel() 119 { 120 ItemTitle = "前端示例", 121 Data = new ObservableCollection<MenuItemModel>() 122 { 123 new MenuItemModel() 124 { 125 ItemTitle = "BasicElements", 126 Data = new ObservableCollection<MenuItemModel>() 127 { 128 new MenuItemModel() 129 { 130 ItemTitle="Icon", PageKey=SystemResource.Page_IconView,IsNew=true 131 },new MenuItemModel() 132 { 133 ItemTitle="Skeleton", PageKey=SystemResource.Page_SkeletonView,IsNew=true 134 }, 135 new MenuItemModel() 136 { 137 ItemTitle="Button", PageKey=SystemResource.Page_ButtonView 138 },new MenuItemModel() 139 { 140 ItemTitle="Form", PageKey=SystemResource.Page_FormView 141 },new MenuItemModel() 142 { 143 ItemTitle="Menu", PageKey=SystemResource.Page_MenuView 144 },new MenuItemModel() 145 { 146 ItemTitle="TabControl", PageKey=SystemResource.Page_TabControl 147 },new MenuItemModel() 148 { 149 ItemTitle="ProgressBar", PageKey=SystemResource.Page_ProgressBar 150 },new MenuItemModel() 151 { 152 ItemTitle="Panel", PageKey=SystemResource.Page_PanelView 153 },new MenuItemModel() 154 { 155 ItemTitle="Tag", PageKey=SystemResource.Page_TagView,IsNew=true 156 },new MenuItemModel() 157 { 158 ItemTitle="Expander", PageKey=SystemResource.Page_ExpanderView 159 },new MenuItemModel() 160 { 161 ItemTitle="Transition", PageKey=SystemResource.Page_TransitionControlView 162 },new MenuItemModel() 163 { 164 ItemTitle="Loading", PageKey=SystemResource.Page_LoadingView 165 },new MenuItemModel() 166 { 167 ItemTitle="GIF", PageKey=SystemResource.Page_GIFImageView 168 },new MenuItemModel() 169 { 170 ItemTitle="ScaleImage", PageKey=SystemResource.Page_ScaleImageView 171 },new MenuItemModel() 172 { 173 ItemTitle="Timeline", PageKey=SystemResource.Page_TimelineView 174 },new MenuItemModel() 175 { 176 ItemTitle="AuxiliaryElement", PageKey=SystemResource.Page_AuxiliaryElementView 177 },new MenuItemModel() 178 { 179 ItemTitle="FlowItemsControl", PageKey=SystemResource.Page_FlowItemsControlView 180 } 181 } 182 }, 183 new MenuItemModel() 184 { 185 ItemTitle = "ComponentExamples", 186 Data = new ObservableCollection<MenuItemModel>() 187 { 188 189 new MenuItemModel() 190 { 191 ItemTitle="AnimationCommand", PageKey=SystemResource.Page_AnimationCommandView 192 },new MenuItemModel() 193 { 194 ItemTitle="ToolTip", PageKey=SystemResource.Page_ToolTipView 195 },new MenuItemModel() 196 { 197 ItemTitle="Badge", PageKey=SystemResource.Page_BadgeView 198 },new MenuItemModel() 199 { 200 ItemTitle="Ripple", PageKey=SystemResource.Page_RippleView,IsNew=true 201 },new MenuItemModel() 202 { 203 ItemTitle="PopupBox", PageKey=SystemResource.Page_PopupBoxView 204 },new MenuItemModel() 205 { 206 ItemTitle="Dialog", PageKey=SystemResource.Page_DialogView 207 },new MenuItemModel() 208 { 209 ItemTitle="Drawer", PageKey=SystemResource.Page_DrawerView 210 },new MenuItemModel() 211 { 212 ItemTitle="DateTime", PageKey=SystemResource.Page_DateTimeView 213 },new MenuItemModel() 214 { 215 ItemTitle="DataGrid", PageKey=SystemResource.Page_DataGrid 216 },new MenuItemModel() 217 { 218 ItemTitle="Pagination", PageKey=SystemResource.Page_PaginationView 219 },new MenuItemModel() 220 { 221 ItemTitle="DropDownMenu", PageKey=SystemResource.Page_ButtonView 222 },new MenuItemModel() 223 { 224 ItemTitle="Upload", PageKey=SystemResource.Page_UploadView 225 },new MenuItemModel() 226 { 227 ItemTitle="ShuttleGrid", PageKey=SystemResource.Page_ButtonView 228 },new MenuItemModel() 229 { 230 ItemTitle="TreeView", PageKey=SystemResource.Page_TreeView 231 },new MenuItemModel() 232 { 233 ItemTitle="Cascader", PageKey=SystemResource.Page_LayCascaderView 234 },new MenuItemModel() 235 { 236 ItemTitle="TreeSelect", PageKey=SystemResource.Page_TreeSelectView 237 },new MenuItemModel() 238 { 239 ItemTitle="Slider", PageKey=SystemResource.Page_Slider 240 },new MenuItemModel() 241 { 242 ItemTitle="Score", PageKey=SystemResource.Page_ButtonView 243 },new MenuItemModel() 244 { 245 ItemTitle="Carousel", PageKey=SystemResource.Page_CarouselView 246 },new MenuItemModel() 247 { 248 ItemTitle="Message", PageKey=SystemResource.Page_MessageView 249 },new MenuItemModel() 250 { 251 ItemTitle="Notification", PageKey=SystemResource.Page_NotificationView 252 },new MenuItemModel() 253 { 254 ItemTitle="NoticeBar", PageKey=SystemResource.Page_NoticeBarView,IsNew=true 255 },new MenuItemModel() 256 { 257 ItemTitle="VRImage", PageKey=SystemResource.Page_VRView,IsNew=true 258 },new MenuItemModel() 259 { 260 ItemTitle="PropertyGrid", PageKey=SystemResource.Page_PropertyGridView,IsNew=true 261 },new MenuItemModel() 262 { 263 ItemTitle="Keyboard", PageKey=SystemResource.Page_KeyboardView 264 } 265 } 266 }, 267 new MenuItemModel() 268 { 269 ItemTitle = "递归菜单", 270 Data = new ObservableCollection<MenuItemModel>() 271 { 272 new MenuItemModel() 273 { 274 ItemTitle="二级菜单", 275 Data = new ObservableCollection<MenuItemModel>() 276 { 277 new MenuItemModel() 278 { 279 ItemTitle="三级菜单", 280 Data = new ObservableCollection<MenuItemModel>() 281 { 282 new MenuItemModel() 283 { 284 ItemTitle="四级菜单", 285 Data = new ObservableCollection<MenuItemModel>() 286 { 287 new MenuItemModel() 288 { 289 ItemTitle="五级菜单", 290 Data = new ObservableCollection<MenuItemModel>() 291 { 292 new MenuItemModel() 293 { 294 ItemTitle="六级菜单" 295 }, 296 } 297 }, 298 } 299 }, 300 } 301 }, 302 } 303 }, 304 } 305 } 306 } 307 }); 308 309 return Task.FromResult(list); 310 } 311 }
5.Home.xaml页面代码
通过 <ContentControl prismRegions:RegionManager.RegionName="{x:Static Nv:SystemResource.Nav_HomeContent}" />实现菜单子页面的注入和跳转
通过ScrollViewer主键实现菜单页面,
<ItemsControl
Padding="0"
Background="Transparent"
BorderThickness="0"
ItemTemplateSelector="{DynamicResource MenuItemSelector}"
ItemsSource="{Binding MenuItemList}">
ItemsControl组件实现菜单项的绑定MenuItemList,ItemTemplateSelector属性实现菜单项的选择切换,DataTemplate属性实现页面的跳转

1 <UserControl 2 x:Class="Home.Views.Home" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:Lay="clr-namespace:LayUI.Wpf.Controls;assembly=LayUI.Wpf" 6 xmlns:Nv="clr-namespace:Core;assembly=Core" 7 xmlns:Selector="clr-namespace:Home.Selector" 8 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 9 xmlns:ex="clr-namespace:LayUI.Wpf.Extensions;assembly=LayUI.Wpf.Extensions" 10 xmlns:local="clr-namespace:Home.Views" 11 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 12 xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Wpf" 13 xmlns:prismRegions="clr-namespace:Prism.Regions;assembly=Prism.Wpf" 14 d:DesignHeight="540" 15 d:DesignWidth="1080" 16 prism:ViewModelLocator.AutoWireViewModel="True" 17 mc:Ignorable="d"> 18 19 <Grid> 20 <Grid.ColumnDefinitions> 21 <ColumnDefinition Width="auto" /> 22 <ColumnDefinition /> 23 </Grid.ColumnDefinitions> 24 <Border Width="200" Background="{DynamicResource Black}"> 25 <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> 26 <ItemsControl 27 Padding="0" 28 Background="Transparent" 29 BorderThickness="0" 30 ItemTemplateSelector="{DynamicResource MenuItemSelector}" 31 ItemsSource="{Binding MenuItemList}"> 32 <ItemsControl.Resources> 33 <Selector:MenuItemDataTemplateSelector x:Key="MenuItemSelector" /> 34 <DataTemplate x:Key="MenuItemsDataTemplate"> 35 <Lay:LayNavExpander 36 Padding="10,0" 37 Header="{ex:Language {Binding ItemTitle}}" 38 IsExpanded="{Binding IsSelected}"> 39 <ItemsControl ItemTemplateSelector="{DynamicResource MenuItemSelector}" ItemsSource="{Binding Data}"> 40 <ItemsControl.ItemsPanel> 41 <ItemsPanelTemplate> 42 <StackPanel /> 43 </ItemsPanelTemplate> 44 </ItemsControl.ItemsPanel> 45 </ItemsControl> 46 </Lay:LayNavExpander> 47 </DataTemplate> 48 <DataTemplate x:Key="MenuItemDataTemplate"> 49 <RadioButton 50 Height="40" 51 Padding="20,0" 52 Command="{Binding RelativeSource={RelativeSource AncestorType=local:Home}, Path=DataContext.GoPageCommand}" 53 CommandParameter="{Binding}" 54 Content="{ex:Language {Binding ItemTitle}}" 55 FocusVisualStyle="{x:Null}" 56 Foreground="White" 57 GroupName="Item" 58 IsChecked="{Binding IsSelected}"> 59 <RadioButton.Template> 60 <ControlTemplate TargetType="RadioButton"> 61 <ControlTemplate.Resources> 62 <BooleanToVisibilityConverter x:Key="BooleanToVisibility" /> 63 </ControlTemplate.Resources> 64 <Grid> 65 <Grid.ColumnDefinitions> 66 <ColumnDefinition /> 67 <ColumnDefinition Width="auto" /> 68 </Grid.ColumnDefinitions> 69 <Border 70 x:Name="bg" 71 Grid.ColumnSpan="2" 72 Background="Transparent" /> 73 <Grid 74 x:Name="line" 75 Width="5" 76 HorizontalAlignment="Left" 77 Background="{StaticResource Green}" 78 Opacity="0" /> 79 <ContentPresenter 80 x:Name="dataContent" 81 Margin="{TemplateBinding Padding}" 82 HorizontalAlignment="Left" 83 VerticalAlignment="Center" 84 IsHitTestVisible="True" 85 Opacity="0.7" /> 86 <Grid Grid.Column="1" Visibility="{Binding IsNew, Converter={StaticResource BooleanToVisibility}}"> 87 <Border 88 Height="20" 89 Margin="5,0" 90 VerticalAlignment="Center" 91 Background="{DynamicResource Gradient}" 92 CornerRadius="10" /> 93 <TextBlock 94 Margin="15,0" 95 VerticalAlignment="Center" 96 Text="new" /> 97 </Grid> 98 </Grid> 99 <ControlTemplate.Triggers> 100 <Trigger Property="IsMouseOver" Value="true"> 101 <Setter TargetName="dataContent" Property="Opacity" Value="1" /> 102 <Trigger.EnterActions> 103 <BeginStoryboard> 104 <Storyboard> 105 <DoubleAnimation 106 Storyboard.TargetName="line" 107 Storyboard.TargetProperty="Opacity" 108 To="1" 109 Duration="0:0:0.3" /> 110 </Storyboard> 111 </BeginStoryboard> 112 </Trigger.EnterActions> 113 <Trigger.ExitActions> 114 <BeginStoryboard> 115 <Storyboard> 116 <DoubleAnimation 117 Storyboard.TargetName="line" 118 Storyboard.TargetProperty="Opacity" 119 To="0" 120 Duration="0:0:0.3" /> 121 </Storyboard> 122 </BeginStoryboard> 123 </Trigger.ExitActions> 124 </Trigger> 125 <Trigger Property="IsChecked" Value="true"> 126 <Setter TargetName="bg" Property="Background" Value="{StaticResource Green}" /> 127 <Setter TargetName="dataContent" Property="Opacity" Value="1" /> 128 <Setter TargetName="dataContent" Property="Opacity" Value="1" /> 129 </Trigger> 130 </ControlTemplate.Triggers> 131 </ControlTemplate> 132 </RadioButton.Template> 133 </RadioButton> 134 </DataTemplate> 135 </ItemsControl.Resources> 136 </ItemsControl> 137 </ScrollViewer> 138 </Border> 139 140 <Lay:LayTransition 141 Grid.Column="1" 142 IsActive="true" 143 Type="{Binding AnimationType}"> 144 <ContentControl prismRegions:RegionManager.RegionName="{x:Static Nv:SystemResource.Nav_HomeContent}" /> 145 </Lay:LayTransition> 146 </Grid> 147 </UserControl>
五、添加其他模块的项目,并实现主菜单中选择页面的跳转
需在App.xaml的后台代码重写方法ConfigureModuleCatalog中进行模块的注入: moduleCatalog.AddModule<SystemConfigModule>();
1.编写模块类SystemConfigModule继承IModule接口,实现RegisterTypes方法,继续页面跳转的注册
containerRegistry.RegisterForNavigation<Views.SysUserInfos>("SysUserInfos");

1 public class SystemConfigModule : IModule 2 { 3 public void OnInitialized(IContainerProvider containerProvider) 4 { 5 6 } 7 8 public void RegisterTypes(IContainerRegistry containerRegistry) 9 { 10 containerRegistry.RegisterForNavigation<Views.SysUserInfos>("SysUserInfos"); 11 } 12 }
2.编写ViewModel类实现页面的绑定和命令实现

1 public class SysUserInfosViewModel : ViewModelBase 2 { 3 private readonly IContainerExtension _container; 4 5 private readonly IRegionManager _regionManager; 6 public SysUserInfosViewModel(IContainerExtension container, IRegionManager regionManager) 7 { 8 _container = container; 9 _regionManager = regionManager; 10 LoadedListData(new LayPagination { JumpIndex = 1,Limit = 10}); 11 ClickCommand = new DelegateCommand(ExcuteClickCommand); 12 PageUpdatedCommand = new DelegateCommand<LayPagination>(LoadedListData); 13 } 14 15 #region 查询命令 16 //查询命令 17 public DelegateCommand ClickCommand { get; set; } 18 19 private void ExcuteClickCommand() 20 { 21 LayDialogParameter dialogParameter = new LayDialogParameter(); 22 dialogParameter.Add("Message", ""); 23 LayDialog.ShowDialog("DialogAlert", dialogParameter, rest => 24 { 25 switch (rest.Result) 26 { 27 case LayUI.Wpf.Enum.ButtonResult.Yes: 28 break; 29 case LayUI.Wpf.Enum.ButtonResult.No: 30 break; 31 case LayUI.Wpf.Enum.ButtonResult.Default: 32 break; 33 default: 34 break; 35 } 36 37 }, "Dialog"); 38 } 39 #endregion 40 41 #region 页面更新 42 public DelegateCommand<LayPagination> PageUpdatedCommand { get; set; } 43 44 private void LoadedListData(LayPagination pagination) 45 { 46 try 47 { 48 var random = new Random(); 49 50 var list = new List<UserInfo>(); 51 list.Clear(); 52 for (int i = 1; i < 16000; i++) 53 { 54 int num = random.Next(1, 101); 55 list.Add(new UserInfo() { Index = i, Name = "测试" + i, ProgressBarValue = num }); 56 }; 57 Total = list.Count(); 58 var temp = list.Skip((pagination.JumpIndex - 1) * pagination.Limit).Take(pagination.Limit).ToList(); 59 ListData.Clear(); 60 foreach (var item in temp) 61 { 62 ListData.Add(item); 63 } 64 65 } 66 catch (Exception ex) 67 { 68 69 throw ex; 70 } 71 } 72 #endregion 73 74 #region 页面属性 75 /// <summary> 76 /// 77 /// </summary> 78 private ObservableCollection<UserInfo> _ListData = new ObservableCollection<UserInfo>(); 79 public ObservableCollection<UserInfo> ListData 80 { 81 get { return _ListData; } 82 set { SetProperty(ref _ListData, value); } 83 } 84 85 /// <summary> 86 /// 控制当前的列展示状态 87 /// </summary> 88 private Visibility _Visibility; 89 public Visibility Visibility 90 { 91 get { return _Visibility; } 92 set { SetProperty(ref _Visibility, value); } 93 } 94 95 /// <summary> 96 /// 97 /// </summary> 98 private bool _IsShow = true; 99 public bool IsShow 100 { 101 get { return _IsShow; } 102 set 103 { 104 SetProperty(ref _IsShow, value); 105 if (value) Visibility = Visibility.Visible; 106 else Visibility = Visibility.Collapsed; 107 } 108 } 109 110 /// <summary> 111 /// 112 /// </summary> 113 private bool _IsActive; 114 public bool IsActive 115 { 116 get { return _IsActive; } 117 set { SetProperty(ref _IsActive, value); } 118 } 119 #endregion 120 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇