Avalonia中使用Prism实现区域导航功能

前言

上一篇文章我们讲了在Avalonia开发中,引入Prism框架来完成项目的MVVM迁移。本章内容将带领大家学习如何在Avalonia中使用Prism框架实现区域导航功能。如果你还不知道Avalonia中如何引入Prism框架,请看我上一篇文章:Avalonia框架下面使用Prism框架实现MVVM模式

新建导航页

我们首先在相应的文件夹下面创建ViewA、ViewB以及他们所对应的ViewModel,创建好的目录结构如下:
在这里插入图片描述
创建View和WPF里面差不多,但是Avalonia需要手动的指定绑定的VM的DataType类型。其实通过后面的验证,其实指定不指定其实在Prism框架下面没有影响,项目依然能够正常运行。但是有一个问题就是如果你设置了DataType类型,你在后期界面绑定数据的时候会有智能提示出来方便开发。
在这里插入图片描述
这里有个小细节需要 特别注意,这里面有个小bug,我们创建的ViewModel或者新引入nuget动态库文件以后,如果我们想在view里面进行引用,应该先全局生成一下解决方案,这样在编码的时候才能出现智能提示,希望官方后期能够修复这个bug.

创建ViewModel

创建ViewModel,这里面其实和WPF里面是一样的,这里就不在赘述,代码如下:

using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaTest.ViewModels
{
    public class ViewAViewModel : ViewModelBase, INavigationAware
    {
        private string _title="ViewA";

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

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            
        }
    }
}

容器里面注册导航资源

我们在App.xaml里面注册导航用到的ViewA和ViewB,代码如下:

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<MainView>();
        containerRegistry.RegisterForNavigation<ViewA,ViewAViewModel>(nameof(ViewA));
        containerRegistry.RegisterForNavigation<ViewB,ViewBViewModel>(nameof(ViewB));
    }

在这里插入图片描述

创建显示区域

在MainView里面创建显示区域,其实和WPF里面是一模一样的。
在这里插入图片描述

ViewModel里面的导航实现

这里面主要通过构造函数传过来一个IRegionManager参数,然后通过这个区域管理对象对我们的区域实现导航功能,其实实现也都和WPF里面一样。
在这里插入图片描述

完整的代码实现

MainView.axaml

<UserControl xmlns="https://github.com/avaloniaui"
             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:vm="clr-namespace:AvaloniaTest.ViewModels"
             xmlns:prism="http://prismlibrary.com/"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="AvaloniaTest.Views.MainView"
             prism:ViewModelLocator.AutoWireViewModel="True"
             x:DataType="vm:MainViewModel">
  <Design.DataContext>
    <!-- This only sets the DataContext for the previewer in an IDE,
         to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
  </Design.DataContext>

  <Grid RowDefinitions="50,*">
    <Grid ColumnDefinitions="*,*,*">
      <TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
      <Button Content="ViewA" Grid.Column="1" Command="{Binding ViewACommand}"></Button>
      <Button Content="ViewB" Grid.Column="2" Command="{Binding ViewBCommand}"></Button>
    </Grid>
    <ContentControl Grid.Row="1" prism:RegionManager.RegionName="mainContent"></ContentControl>
  </Grid>

</UserControl>

MainViewModel.cs

using AvaloniaTest.Views;
using Prism.Commands;
using Prism.Regions;

namespace AvaloniaTest.ViewModels;

public class MainViewModel : ViewModelBase
{

    private readonly IRegionManager _regionManager;
    public MainViewModel(IRegionManager regionManager) {
        _regionManager = regionManager;
        _regionManager.RegisterViewWithRegion("mainContent", nameof(ViewB));

        ViewACommand = new DelegateCommand(() => {
            _regionManager.RequestNavigate("mainContent", nameof(ViewA));
        });

        ViewBCommand = new DelegateCommand(() => {
            _regionManager.RequestNavigate("mainContent", nameof(ViewB));
        });
    }

    public DelegateCommand ViewACommand { get; set; }
    public DelegateCommand ViewBCommand { get; set; }

    public string Greeting => "Welcome to Avalonia!";

}

ViewA.axaml

<UserControl xmlns="https://github.com/avaloniaui"
             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:vm="using:AvaloniaTest.ViewModels"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:DataType="vm:ViewAViewModel"
             x:Class="AvaloniaTest.Views.ViewA" Background="Red">
  <TextBlock Text="{Binding Title}"></TextBlock>
</UserControl>

ViewAViewModel.cs

using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaTest.ViewModels
{
    public class ViewAViewModel : ViewModelBase, INavigationAware
    {
        private string _title="ViewA";

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

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            
        }
    }
}

ViewB.axaml

<UserControl xmlns="https://github.com/avaloniaui"
             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:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="AvaloniaTest.Views.ViewB" Background="Green">
  <TextBlock Text="{Binding Title}"></TextBlock>
</UserControl>

ViewBViewModel.cs

using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaTest.ViewModels
{
    public class ViewBViewModel : ViewModelBase, INavigationAware
    {
        private string _title = "ViewB";

        public string Title
        {
            get => _title;
            set
            {
                SetProperty(ref _title, value);
            }
        }
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
        }
    }
}

App.axaml

<prism:PrismApplication xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"
             x:Class="AvaloniaTest.App"
             RequestedThemeVariant="Default">
             <!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->

    <Application.Styles>
        <FluentTheme />
    </Application.Styles>
</prism:PrismApplication>

App.axaml.cs

using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using AvaloniaTest.ViewModels;
using AvaloniaTest.Views;
using Prism.DryIoc;
using Prism.Ioc;

namespace AvaloniaTest;

public partial class App : PrismApplication
{
    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
        base.Initialize();
    }

    public override void OnFrameworkInitializationCompleted()
    {
        //if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        //{
        //    desktop.MainWindow = new MainWindow
        //    {
        //        DataContext = new MainViewModel()
        //    };
        //}
        //else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
        //{
        //    singleViewPlatform.MainView = new MainView
        //    {
        //        DataContext = new MainViewModel()
        //    };
        //}

        base.OnFrameworkInitializationCompleted();
    }

    protected override AvaloniaObject CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<MainView>();
        containerRegistry.RegisterForNavigation<ViewA,ViewAViewModel>(nameof(ViewA));
        containerRegistry.RegisterForNavigation<ViewB,ViewBViewModel>(nameof(ViewB));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/221684.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【WPF.NET开发】构造动态布局

本文内容 系统必备创建项目配置默认的 Grid Panel 控件向面板中添加控件测试布局汇总所有内容后续步骤 在动态定位中&#xff0c;您通过指定子元素相对于父元素应该如何排列以及应该如何包装来排列子元素。 您还可以将窗口和控件设置为在其内容扩展时自动扩展。 适用于 Vis…

Oracle merge into语句(merge into Statement)

在Oracle中&#xff0c;常规的DML语句只能完成单一功能&#xff0c;&#xff0c;例如insert/delete/update只能三选一&#xff0c;而merge into语句可以同时对一张表进行更新/插入/删除。 目录 一、基本语法 二、用法示例 2.1 同时更新和插入 2.2 where子句 2.3 delete子句 2.4…

数据库Delete的多种用法

数据库的Delete操作是用来删除数据库中的数据记录的&#xff0c;它是数据库操作中的一种重要操作&#xff0c;能够帮助用户删除不需要的数据&#xff0c;以便保持数据库的整洁和高效。在使用Delete操作时&#xff0c;需要注意确保操作的准确性和安全性&#xff0c;以免误删重要…

[JavaScript前端开发及实例教程]计算器井字棋游戏的实现

计算器&#xff08;网页内实现效果&#xff09; HTML部分 <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>My Calculator&l…

Ruff智能物联网网关助力工厂数智化运营,实现产量提升5%

数字化转型是大势所趋&#xff0c;以工业互联网为代表的数实融合是发展数字经济的重要引擎&#xff0c;也是新质生产力的一大助力。工业互联网是新工业革命的重要基石&#xff0c;加快工业互联网规模化应用&#xff0c;是数字技术和实体经济深度融合的关键支撑&#xff0c;是新…

回归预测 | MATLAB实现CNN-BiLSTM(卷积双向长短期记忆神经网络

效果一览 基本介绍 提出一种同时考虑时间与空间因素的卷积&#xff0d;双向长短期记忆&#xff08; CNN-BiLSTM&#xff09;模型&#xff0c;将具有空间局部特征提取能力的卷积神经网络&#xff08;CNN&#xff09;和具有能同时考虑前后方向长时间信息的双向长短期记忆&#xf…

JavaScript基础知识21——for循环

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 今天学习for循环&#xff0c;以下为学习笔记。 1、while循环和for循环有啥不同&#xff1f; 1.1、在实际开发中&#xff0c;while循环用来解决循环次数不确定时使用&#xff0c;当一个循环不确定会循环多少次时&#…

【每日OJ —— 94. 二叉树的中序遍历】

每日OJ —— 94. 二叉树的中序遍历 1.题目&#xff1a;94. 二叉树的中序遍历2.解法2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目&#xff1a;94. 二叉树的中序遍历 2.解法 2.1.算法讲解 1.首先如果在每次每个节点遍历的时候都去为数组开辟空间&#xff0c;这样的效率太低…

OWASP安全练习靶场juice shop-更新中

Juice Shop是用Node.js&#xff0c;Express和Angular编写的。这是第一个 完全用 JavaScript 编写的应用程序&#xff0c;列在 OWASP VWA 目录中。 该应用程序包含大量不同的黑客挑战 用户应该利用底层的困难 漏洞。黑客攻击进度在记分板上跟踪。 找到这个记分牌实际上是&#…

【PyTorch】tensorboardX的安装和使用

文章目录 1. tensorboardX的安装2. tensorboardX的使用 tensorboardX是一种能将训练过程可视化的工具 1. tensorboardX的安装 安装命令&#xff1a; pip install tensorboardXVSCode集成了TensorBoard支持&#xff0c;不过事先要安装torch-tb-profiler&#xff0c;安装命令&…

文件管理和操作工具Path Finder mac功能介绍

Path Finder mac是一款Mac平台上的文件管理和操作工具&#xff0c;提供了比Finder更丰富的功能和更直观的用户界面。它可以帮助用户更高效地浏览、复制、移动、删除和管理文件&#xff0c;以及进行各种高级操作。 Path Finder mac软件功能 - 文件浏览&#xff1a;可以快速浏览文…

如何购买华为云服务器

华为云是华为推出的云计算服务平台&#xff0c;旨在为企业和个人提供全面的云端解决方案。它提供了包括计算、存储、数据库、人工智能、大数据、安全等多种云服务&#xff0c;覆盖了基础设施、平台和软件级别的需求。华为云致力于构建安全可信赖的云计算基础设施&#xff0c;以…

vite初识

Vite是伴随着Vue3正式版一起发布的&#xff0c;最开始Vite 1.0的版本是为Vue3服务的&#xff0c;并不是跨框架的。之后半年时间左右&#xff0c;出现了Vite 2.0版本&#xff0c;Vite 2.0真正脱离了和Vue3的强关联&#xff0c;以插件的方式&#xff0c;可以集成到目前流行的主流…

【每日一题】到达首都的最少油耗

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;贪心深搜 写在最后 Tag 【递归/深度优先搜索】【树】【2023-12-05】 题目来源 2477. 到达首都的最少油耗 题目解读 每个城市都有一位代表需要前往城市 0 进行开会。每个城市都有一辆座位数为 seats 的汽车&#xff0…

2023.12.4 关于 Spring Boot 统一异常处理

目录 引言 统一异常处理 异常全部监测 引言 将异常处理逻辑集中到一个地方&#xff0c;可以避免在每个控制器或业务逻辑中都编写相似的异常处理代码&#xff0c;这降低了代码的冗余&#xff0c;提高了代码的可维护性统一的异常处理使得调试和维护变得更加容易&#xff0c;通…

Python智能语音识别语翻译平台|项目后端搭建

Python程序设计基础&#xff0c;第三方库Django、requests、hashlib、pyttsx3等的使用&#xff0c;百度API语音识别业务接口、文本朗读业务接口、翻译业务接口的传入。 01、任务实现步骤 任务描述&#xff1a;本任务利用Django框架搭建智能语音识别与翻译平台的后端&#xff0…

leetcode:统计感冒序列的数目【数学题:组合数含逆元模版】

1. 题目截图 2.题目分析 需要把其分为多个段进行填充 长为k的段&#xff0c;从两端往中间填充的方案数有2 ** (k - 1)种 组合数就是选哪几个数填哪几个段即可 3.组合数含逆元模版 MOD 1_000_000_007 MX 100_000# 组合数模板 fac [0] * MX fac[0] 1 for i in range(1, MX…

GPT-Crawler一键爬虫构建GPTs知识库

GPT-Crawler一键爬虫构建GPTs知识库 写在最前面安装node.js安装GPT-Crawler启动爬虫结合 OpenAI自定义 assistant自定义 GPTs&#xff08;笔者用的这个&#xff09; 总结 写在最前面 GPT-Crawler一键爬虫构建GPTs知识库 能够爬取网站数据&#xff0c;构建GPTs的知识库&#xf…

LeetCode //C - 221. Maximal Square

221. Maximal Square Given an m x n binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area. Example 1: Input: matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,…

计算机操作系统2

1.计算机操作系统的发展和分类 2.操作系统的运行机制 3.中断 3.1.中断&#xff08;关键作用&#xff09; 4.系统调用 5.操作系统的内核 6.操作系统的体系结构 7.开机过程&#xff08;操作系统引导&#xff09;