WPF + DevExpress学习04 整合Prism+MVVM

安装包
	Prism.Unity 
	Prism.Wpf

MVVM登录功能

首先简单的说一下 MVVM 是一种数据驱动试图的模式 通过修改数据来触发界面上的变化,Prism.Unity 是一个IOC 容器框架

App.cs

// 首先继承 PrismApplication
 public partial class App : PrismApplication{
     // 主界面
    protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>;
        }
        // 初始化前的判断
	     protected override void InitializeShell(Window shell)
        {
            if (Container.Resolve<Login>().ShowDialog() == false)
            {
                Application.Current?.Shutdown();
            }
            else
            {
                base.InitializeShell(shell);
            }
        }
        // 容器注册服务的地方
       protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.Register<ILoginService, LoginService>();
            containerRegistry.RegisterScoped<DBContext>();
        }
 }

Login界面

<Window x:Class="NhxProjectSystem.Main.Views.Login"
        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:NhxProjectSystem.Main.Views"
        mc:Ignorable="d"
        Name="loginWindow"
        WindowStartupLocation="CenterScreen"
        Title="登录" MaxHeight="450" MaxWidth="700" MinWidth="700" MinHeight="450" 
        ResizeMode="NoResize "
        xmlns:prism="http://prismlibrary.com/"
         prism:ViewModelLocator.AutoWireViewModel="True"
        >
    <Grid  >
        <DockPanel>
            <Image  Grid.Column="0" Source="/Image/LoginBg.png" Height="450" Width="400" />
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"   >
                <TextBlock Width="280" TextAlignment="Center" Padding="0,30,0,30" FontSize="27" LineHeight="30" >系统</TextBlock>
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" >
                    <TextBlock Width="260"  >账号</TextBlock>
                    <TextBox TextWrapping="Wrap"  Text="{Binding UserName,Mode=TwoWay}" Name="UserName"  Padding="0,5"  Margin="0,0,0,20" BorderBrush="#40a9ff" />
                    <TextBlock >密码</TextBlock>
                    <TextBox TextWrapping="Wrap"   Text="{Binding Password,Mode=TwoWay}"  Name="Password"  Padding="0,5" Margin="0,0,0,20" />
                    <Button  Content="登 录"   Padding="0,5" CommandParameter="{Binding ElementName=loginWindow}"  Command="{Binding LoginCommand}" />
                </StackPanel>
            </StackPanel>
            
        </DockPanel>
     

    </Grid>
</Window>

LoginViewModel.cs 登录

    public interface ILoginService
    {
        User UserLogin(string username, string password);
    }
      public class LoginService : ILoginService
    {
        [Dependency]  // using Unity;
        public DBContext _DBContext { get; set; }
        public User UserLogin(string username, string password)
        {
         return   _DBContext .NhxUsers.AsNoTracking().FirstOrDefault(c=>c.Password==password&&c.Account==username);
        }
    }
 public class LoginViewModel : BindableBase
    {
        [Dependency]  //属性注入;
        public ILoginService _loginService { get; set; }
        private string userName = "";
        private string password = "";
        public string UserName
        {
            get { return userName; }
            set { SetProperty(ref userName, value); }
        }
        public string Password
        {
            get { return password; }
            set { SetProperty(ref password, value); }
        }
        // 命令
        ICommand? loginCommand;
        public ICommand LoginCommand
        {
            get
            {
                if (loginCommand == null)
                {
                    loginCommand = new DelegateCommand<object>(UserLogin);
                }
                return loginCommand;
            }
        }
        void UserLogin(object obj)
        {
            var LoginUser=_loginService.UserLogin(this.UserName, this.Password);
            if (LoginUser == null)
            {
                MessageBox.Show("用户名或密码错误");
                return;
            }
      
            (obj as Window).DialogResult = true;
        }
    }
}

模块化开发

原本是准备按照正常的方式来实现 但是看了一些文章和实现方式发现了一种更好的更解耦的方式 中间踩了很多坑 记录一下
在这里插入图片描述
这是我的布局图 看似很简单 我当初实现的时候也是这样想的
现在要考虑三个问题 1 动态菜单 2 工具栏事件的消息订阅 我在每个独立的模块页面都可以监听 3 如何实现切换菜单 还要考虑模块化 话不多说直接上代码
先了解 RegionManager ,其次就是Prism 模块的加载机制
在这里插入图片描述
项目结构 模块内有两个界面 基础设置 和 甘特图界面

 public interface IView
    {
    }
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Application";

        //Region管理对象
        private IRegionManager _regionManager;
        private IModuleCatalog _moduleCatalog;
        private ObservableCollection<IModuleInfo> _modules;
        private DelegateCommand _loadModulesCommand;
        private DelegateCommand _openViewA;
        private DelegateCommand _openViewB;
        private DelegateCommand _goBackView;
        private DelegateCommand _goForwardView;
        private IModuleInfo _moduleInfo;

        //导航日志
        private IRegionNavigationJournal _navigationJournal;

        public IView View { get; set; }

        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public ObservableCollection<IModuleInfo> Modules
        {
            get => _modules ?? (_modules = new ObservableCollection<IModuleInfo>());
        }

        public DelegateCommand LoadModulesCommand { get => _loadModulesCommand = new DelegateCommand(InitModules); }

        public IModuleInfo ModuleInfo
        {
            get
            {
                return _moduleInfo;
            }

            set
            {
                _moduleInfo = value;
                Navigate(value);
            }
        }

        public DelegateCommand OpenViewA
        {
            get => _openViewA ?? (_openViewA = new DelegateCommand(OpenViewAAction));
        }

        public DelegateCommand OpenViewB
        {
            get => _openViewB ?? (_openViewB = new DelegateCommand(OpenViewBAction));
        }

        public DelegateCommand GoBackView { get => _goBackView ?? (_goBackView = new DelegateCommand(GoBackViewAction)); }

        public DelegateCommand GoForwardView { get => _goForwardView ?? (_goForwardView = new DelegateCommand(GoForwardViewAction)); }

        public MainWindowViewModel(IRegionManager regionManager, IModuleCatalog moduleCatalog)
        {
            _regionManager = regionManager;
            _moduleCatalog = moduleCatalog;
        }

        private void OpenViewAAction()
        {
            //_regionManager.RequestNavigate("ContentRegion", "TempViewA");

            _regionManager.RequestNavigate("ContentRegion", "TempViewA", arg =>
            {
                //记录导航日志上下文
                _navigationJournal = arg.Context.NavigationService.Journal;
            });
        }

        private void OpenViewBAction()
        {
            //_regionManager.RequestNavigate("ContentRegion", "TempViewB");

            _regionManager.RequestNavigate("ContentRegion", "TempViewB", arg =>
            {
                //记录导航日志上下文
                _navigationJournal = arg.Context.NavigationService.Journal;
            });
        }

        /// <summary>
        /// 导航日志:导航到上一个
        /// </summary>
        private void GoBackViewAction()
        {
            if (_navigationJournal.CanGoBack)
            {
                _navigationJournal.GoBack();
            }
        }

        /// <summary>
        /// 导航日志:导航到下一个
        /// </summary>
        private void GoForwardViewAction()
        {
            if (_navigationJournal.CanGoForward)
            {
                _navigationJournal.GoForward();
            }
        }

        public void InitModules()
        {
            //var dirModuleCatalog =;
            Modules.AddRange(_moduleCatalog.Modules);
        }

        private void Navigate(IModuleInfo info)
        {
            var paramete = new NavigationParameters();
            _regionManager.RequestNavigate("ContentRegion", $"{info.ModuleName}View", arg =>
            {
                //记录导航日志上下文
                _navigationJournal = arg.Context.NavigationService.Journal;
            });
          //  _regionManager.RequestNavigate("ContentRegion", $"{info.ModuleName}View", paramete);
        }
    }
<Window xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"  x:Class="NhxProjectSytem.Main.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/" 
        xmlns:dxa="http://schemas.devexpress.com/winfx/2008/xaml/accordion"
        prism:ViewModelLocator.AutoWireViewModel="True"

        Title="{Binding Title}" Height="350" Width="525" >
    <DockPanel>
        <dxdo:DockLayoutManager FloatingMode="Desktop" ClosedPanelsBarVisibility="Never">
            <dxdo:LayoutGroup Orientation="Horizontal">
                <dxdo:LayoutPanel Name="Navigation" Caption="导航"  AllowClose="False" ItemWidth="200">
                    <dxa:AccordionControl    ItemsSource="{Binding Modules}"     Name="Menus"  SelectedItem="{Binding ModuleInfo}" >
                        
                        <dxa:AccordionControl.ItemContainerStyle>
                            <Style TargetType="dxa:AccordionItem">
                                <Setter Property="Header" Value="{Binding ModuleName}"/>
                            </Style>
                        </dxa:AccordionControl.ItemContainerStyle>
                       
                    </dxa:AccordionControl>
                </dxdo:LayoutPanel>
                <dxdo:DocumentPanel  >
                    <ContentControl  prism:RegionManager.RegionName="ContentRegion"/>
                </dxdo:DocumentPanel>
            </dxdo:LayoutGroup>
            
        </dxdo:DockLayoutManager>
    </DockPanel>

</Window>

App

 两种添加模块的方式
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }
        //protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        //{
         
        //    // 1 添加模块
        //    moduleCatalog.AddModule<GanttProjectModule>();
        //    moduleCatalog.AddModule<BasicSettingModule>();
        //    base.ConfigureModuleCatalog(moduleCatalog);
        //}
        protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
        {
            base.ConfigureRegionAdapterMappings(regionAdapterMappings);
        }
        // 2
        protected override IModuleCatalog CreateModuleCatalog()
        {
            return new DirectoryModuleCatalog() { ModulePath = @".\" };  

        }
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
       
        }
    }

实例界面

// Module 这个特性只有在反射的时候才生效
[Module(ModuleName = "BasicSetting")]
    public class BasicSettingModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            var regionManager = containerProvider.Resolve<IRegionManager>();
            //通过ContentRegion管理导航默认初始页面ContactView
            var contentRegion = regionManager.Regions["ContentRegion"];
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<BasicSettingView>();
        }
    }
     public class BasicSettingViewModel : BindableBase, INavigationAware
    {
        private string _message;
        public string Message
        {
            get { return _message; }
            set { SetProperty(ref _message, value); }
        }

        public BasicSettingViewModel()
        {
            Message = "View A from your Prism Module";
        }
        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
        {
            bool result = true;

            // this is demo code only and not suitable for production. It is generally
            // poor practice to reference your UI in the view model. Use the Prism
            // IDialogService to help with this.
            if (MessageBox.Show("Do you to navigate?", "Navigate?", MessageBoxButton.YesNo) == MessageBoxResult.No)
                result = false;

            continuationCallback(result);
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            //是否创建新示例。为true的时候表示不创建新示例,页面还是之前的;如果为false,则创建新的页面。
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            //导航离开当前页面前。
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            //导航到当前页面前, 此处可以传递过来的参数以及是否允许导航等动作的控制。
        }
    }
····
简单 完成 这个模块不同方式卡我了将近两个小时 经过仔细排查和测试才发现这个坑 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: WPF是一种基于XAML语言的用户界面开发框架,使开发人员能够轻松创建漂亮和高效的桌面应用程序。MVVM是一种模式,它在WPF应用程序中广泛使用,它提供了一种分离UI和业务逻辑的方式,从而简化了代码结构。Prism是一个开源框架,它基于MVVM模式和WPF框架,提供了一些技术和工具,使开发人员能够更轻松地构建复杂的WPF应用程序。 使用WPF MVVM Prism框架可以帮助开发人员提高应用程序的可维护性和可扩展性。通过MVVM,开发人员可以创建一个适应各种应用程序场景的模型,并将其与UI分离。数据绑定和命令绑定使开发人员能够更轻松地将模型中的数据和逻辑与UI控件集成起来。Prism框架还提供了一些工具和功能,如模块化应用程序开发、事件聚合器、导航、对话框、异常处理等功能。这些工具使开发人员能够更轻松地构建复杂的应用程序,并提供了一种可扩展和可重用的方法。 总之,使用WPF MVVM Prism可以使开发人员更轻松地构建复杂的应用程序,并提高应用程序的可维护性和可扩展性。开发人员可以根据自己的需求选择使用这个框架来开发WPF应用程序,从而提高他们的工作效率和代码质量。 ### 回答2: WPF MVVM Prism是一种基于Windows Presentation Foundation(WPF)的软件开发模式,采用了MVVM(Model-View-ViewModel)设计模式和Prism框架来实现软件开发。MVVM是一种在WPF应用程序中使用的设计模式,它将应用程序的视图(View)与应用程序的模型(Model)分离开来,通过ViewModel来连接二者。Prism是一个帮助开发人员编写出复杂、可管控、可扩展和可维护的WPF应用程序的框架。 WPF MVVM Prism提供了很多好处:首先,它能实现软件的可重用性,通过将代码和视图分离,使得代码可以在多个不同的视图中重复使用,提高了开发效率。其次,它可以提高软件的可维护性,通过将逻辑和视图分离,确保逻辑代码与UI代码之间更少的耦合,提高了软件的可扩展性。此外,它还可以提高软件的可测试性,由于MVVM模式中将视图和逻辑分离开,所以开发人员可以更容易地编写出单元测试代码,来测试逻辑代码。最后,由于Prism框架提供了一些通用的,可定制的模块和服务,使得开发人员可以更快地实现常见功能、缩短开发时间。 总之,WPF MVVM Prism是一种高效、可扩展和易于维护的软件开发模式,它将视图和逻辑分离,提高了软件的可重用性和可测试性,同时也提高了软件的可扩展性和可复用性。 ### 回答3: WPF是一种桌面应用程序框架,它允许您为Windows创建高度交互式和可视化的应用程序界面。MVVM是一种软件编程模式,它将用户界面(UI)与业务逻辑分离,以便更好地实现可维护,可扩展和可组合的代码。Prism是一个WPF和Silverlight应用程序的组件库,它提供了一些可重用和可扩展的基础设施组件,帮助您更快速地构建、测试和维护WPF应用程序。因此,WPF MVVM Prism的组合可以帮助您更轻松高效地开发WPF应用程序。您可以使用MVVM模式来改进应用程序的结构和测试,使用Prism来更好地组织和可扩展您的代码,以及使用WPF来实现交互丰富的UI。同时还可以使用Prism提供的事件聚合器、导航器和模块化架构,实现更灵活的应用程序设计。WPF MVVM Prism的组合提供了一种更有效的方式来构建WPF应用程序,以满足现代用户体验的需求,并且更容易测试和维护,因此它已成为WPF应用程序开发的重要组合。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值