C# 从零开始使用Layui.Wpf库开发WPF客户端

 一、简介

  最近需要开发一个桌面版的工具软件,之前用得更多的是Winform,作为一个全干工程师,我们也要兼顾下WPF,趁此机会再研究下开源控件库。

  MaQaQ:Winform真好用(有个HZHControls控件库,值得一看)。

二、准备工作

  找了下开源控件库,诸如MaterialDesignInXAMLHandyControlAduSkinAdonis-UIPanuon.WPF.UIDMSkin等等,以上这些我们都暂时不看。

  本次选用的控件库是Layui.WPF: GitHub - Layui-WPF-Team/Layui-WPF: 这是一个WPF版的Layui前端UI样式库

  选用的原因是我的渣渣网络在打开其他库的时候都加载很慢,只有它脱颖而出,这就是缘分啊。

  MaQaQ:实际上MaterialDesignInXAML跟HandyControl我之前在别的项目有用过,这两个star数都挺高的,用起来也不错,HandyControl在Gitee上也有库,有兴趣的朋友可以去看看,这次我只是想试试新东西。  

  顺利访问到了GitHub库,我打开了里面的学习文档,他只给了我一个Hello world,真是干!得好。再往下翻,找到了使用说明:

C# 从零开始使用Layui.Wpf库开发WPF客户端

   使用说明很简洁,看起来很轻松就能用上了,但我不信。那我们就去把源码下载下来吧,感恩开发者,他还给了示例(搬砖党狂喜啊)。打开程序源码,根据提示安装了.net5跟.net7后成功加载,找到LayuiApp,这是示例项目:

C# 从零开始使用Layui.Wpf库开发WPF客户端

  运行后界面如下(PS:右上角的公告写得真好,值得一读!!!):

C# 从零开始使用Layui.Wpf库开发WPF客户端

三、开发

  作为一个wpf菜鸡+资深搬砖党,此时不忙搬运,我们先打开LayuiApp的MainWindow.xaml,仔细研究一番:

C# 从零开始使用Layui.Wpf库开发WPF客户端

  可以看到,原项目采用的是prism框架(一个用于构建复杂但组织良好的 WPF 应用程序的框架,实际上我并不认识它,这是通义千问告诉我的),总之,prism:ViewModelLocator.AutoWireViewModel="True"这一句,就是用于自动关联视图与视图模型。

  创建一个新的WPF程序,这里还是用我熟悉的.net6,慎重思考1秒后决定命名为ServerControlSystem,新建的项目里面自带有MainWindow.xaml。

  Nuget上引用LayUI.Wpf和Prism的相关库:

C# 从零开始使用Layui.Wpf库开发WPF客户端

   为了实现prism的自动关联,我们要新建两个文件夹,Views和ViewModels,将MainWindow.xaml移动到Views文件夹下,在ViewModels文件夹中对应新建MainWindowViewModel.cs:

C# 从零开始使用Layui.Wpf库开发WPF客户端

   当然,也可以自定义,这就需要我们自己去修改App.xaml.cs,添加配置:

protected override void ConfigureViewModelLocator() {     base.ConfigureViewModelLocator();     ViewModelLocationProvider.Register<MainWindow, MainWindowViewModel>(); }

  这里我们还是用的自动关联,因为移动了MainWindow的位置,所以要对应修改下命名空间的路径(不想改你就直接删了重建吧):

  MainWindow.xaml:

<Window x:Class="ServerControlSystem.Views.MainWindow"...> ... </Window>

  MainWindow.xaml.cs:

public partial class MainWindow : Window

  而在prism框架下,一般要将App的基类改为PrismApplication:

  App.xaml:

C# 从零开始使用Layui.Wpf库开发WPF客户端

<prism:PrismApplication x:Class="ServerControlSystem.App"              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"              xmlns:local="clr-namespace:ServerControlSystem"     xmlns:prism="http://prismlibrary.com/">     <Application.Resources>         <ResourceDictionary>             <ResourceDictionary.MergedDictionaries>                 <ResourceDictionary Source="pack://application:,,,/LayUI.Wpf;component/Themes/Default.xaml" />             </ResourceDictionary.MergedDictionaries>         </ResourceDictionary>     </Application.Resources> </prism:PrismApplication>

View Code

  App.xaml.cs:

public partial class App : PrismApplication

  同时在prism框架下,一般是通过重写CreateShell方法来指定主窗口,且需要实现继承的RegisterTypes:

C# 从零开始使用Layui.Wpf库开发WPF客户端

public partial class App : PrismApplication {     protected override Window CreateShell()     {         return Container.Resolve<MainWindow>();     }     protected override void OnStartup(StartupEventArgs e)     {         base.OnStartup(e);         DispatcherUnhandledException += App_DispatcherUnhandledException;     }     private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)     {         LayMessage.Error(e.Exception.Message);         //记录日志         e.Handled = true;     }     protected override void RegisterTypes(IContainerRegistry containerRegistry)     {         //注入自定义接口         LayDialog.Register(Container.Resolve<IContainerExtension>());     } }

View Code

  现在,我们可以开始快乐搬运了,先小搬一下MainWindow.xaml,这里我们只是验证控件库的调用,所以就试一下Lay:LayTitleBar:

C# 从零开始使用Layui.Wpf库开发WPF客户端

<Window x:Class="ServerControlSystem.Views.MainWindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:Lay="clr-namespace:LayUI.Wpf.Controls;assembly=LayUI.Wpf"         xmlns:prism="http://prismlibrary.com/"     Width="1080"     Height="600"     prism:ViewModelLocator.AutoWireViewModel="True"     AllowsTransparency="True"     WindowStartupLocation="CenterScreen"     WindowStyle="None"     Title="MainWindow" >     <Grid>         <Lay:LayTitleBar             Background="{DynamicResource LighCyan}"             CornerRadius="4"             ResizeMode="CanResize"             WindowState="{Binding WindowState, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">                     </Lay:LayTitleBar>     </Grid> </Window>

View Code

  然后再看模型,先实现基类ViewModelBase:

C# 从零开始使用Layui.Wpf库开发WPF客户端

public abstract class ViewModelBase : BindableBase, INavigationAware, IRegionMemberLifetime, IConfirmNavigationRequest {     /// <summary>     /// 导航器     /// </summary>     public IRegionManager Region;     /// <summary>     /// 弹窗服务     /// </summary>     public IDialogService Dialog;     /// <summary>     /// 事件聚合器     /// </summary>     public IEventAggregator Event;     public ViewModelBase()     {     }     public ViewModelBase(IContainerExtension container)     {         this.Region = container.Resolve<IRegionManager>();         this.Dialog = container.Resolve<IDialogService>();         this.Event = container.Resolve<IEventAggregator>();     }     private DelegateCommand _LoadedCommand;     public DelegateCommand LoadedCommand =>         _LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand));     /// <summary>     ///初始化界面加载     /// </summary>     public virtual void ExecuteLoadedCommand()     {      }     /// <summary>     /// 控制视图是否被缓存     /// </summary>     public bool KeepAlive => false;      public virtual void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)     {         continuationCallback(true);     }     /// <summary>     /// 控制实例是否被缓存     /// </summary>     /// <param name="navigationContext"></param>     /// <returns></returns>     public virtual bool IsNavigationTarget(NavigationContext navigationContext)     {         return false;     }     /// <summary>     /// 导航离开当前ViewModel时被调用     /// </summary>     /// <param name="navigationContext"></param>     public virtual void OnNavigatedFrom(NavigationContext navigationContext)     {     }     /// <summary>     /// 导航到当前ViewModel时被调用     /// </summary>     /// <param name="navigationContext"></param>     public virtual void OnNavigatedTo(NavigationContext navigationContext)     {      } }

View Code

  再实现MainWindowViewModel:

C# 从零开始使用Layui.Wpf库开发WPF客户端

public class MainWindowViewModel : ViewModelBase, IWindowAware {     private WindowState _WindowState;     /// <summary>     /// 窗体状态     /// </summary>     public WindowState WindowState     {         get { return _WindowState; }         set { _WindowState = value; RaisePropertyChanged(); }     }     public MainWindowViewModel(IContainerExtension container) : base(container)     {      }     public override void ExecuteLoadedCommand()     {         base.ExecuteLoadedCommand();     }     public bool CanClosing()     {         var res = MessageBox.Show("确定关闭窗体吗?", "提示", MessageBoxButton.OKCancel);         if (res == MessageBoxResult.OK) return true;         else return false;     } }

View Code

  到这一步基本就完成了,编译生成一下,运行后就能得到一个简陋的空界面:

C# 从零开始使用Layui.Wpf库开发WPF客户端

   之后,就可以根据需要,自己添加控件了。比如,你可以加上,标题栏就会美观一点:

<Lay:LayTitleBar.Header>     <Border Height="40">     </Border> </Lay:LayTitleBar.Header>

四、总结

  Winform真好写。

发表评论

您必须 [ 登录 ] 才能发表留言!

相关文章