Wpf 使用 Prism 实战开发Day20

备忘录功能页面完善以及优化

备忘录功能基本跟前一章节的待办事项差不多一至,就不再做过多的笔述了

一.备忘录功能完整页面源码

MemoView.xaml

<UserControl x:Class="MyToDo.Views.MemoView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyToDo.Views"
             mc:Ignorable="d" 
             xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
              xmlns:cv="clr-namespace:MyToDo.Common.Converters"
              xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <cv:IntToVisibilityConveter x:Key="IntToVisibility"/>
    </UserControl.Resources>
    <md:DialogHost>
        <md:DrawerHost IsRightDrawerOpen="{Binding IsRightDrawerOpen}">
            <!--设计右边弹出层-->
            <md:DrawerHost.RightDrawerContent>
                <!--定义弹出层的内容区域-->
                <DockPanel Width="300" LastChildFill="False">
                    <TextBox Text="{Binding CurrentDto.Title}" md:HintAssist.Hint="请输入备忘录概要" Margin="20,0" DockPanel.Dock="Top"/>
                    <TextBox Text="{Binding CurrentDto.Content}" md:HintAssist.Hint="请输入备忘录内容" Margin="20" MinHeight="100" DockPanel.Dock="Top"/>
                    <Button Command="{Binding ExecuteCommand}" CommandParameter="保存" Content="添加到备忘录"  DockPanel.Dock="Top" Margin="20,0" />
                </DockPanel>
            </md:DrawerHost.RightDrawerContent>

            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>

                <StackPanel Margin="15,0,0,0" Orientation="Horizontal">
                    <!--设置绑定模式和更新数据源类型-->
                    <TextBox Text="{Binding Search,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="250" VerticalAlignment="Center" md:HintAssist.Hint="查找备忘录..." md:TextFieldAssist.HasClearButton="True">
                        <!--搜索框绑定回车事件-->
                        <TextBox.InputBindings>
                            <!--通过Key 绑定-->
                            <KeyBinding Key="Enter"  Command="{Binding ExecuteCommand}" CommandParameter="查询"/>
                        </TextBox.InputBindings>
                    </TextBox>
                </StackPanel>
                <Button HorizontalAlignment="Right" Content="+ 添加备记录" Margin="10,5" Command="{Binding ExecuteCommand}" CommandParameter="新增" />
                <!--当查不到数据时,要显示的图片。添加转换器来控制,要不要显示这个图片-->
                <StackPanel Grid.Row="1" VerticalAlignment="Center" Visibility="{Binding MemoDtos.Count,Converter={StaticResource IntToVisibility}}">
                    <Image Source="/Images/NoData.png" Width="620" Height="220"/>
                    <TextBlock Margin="0,10" FontSize="18" HorizontalAlignment="Center" Text="哇哦,暂无数据"/>
                </StackPanel>
                <ScrollViewer Grid.Row="1" >
                    <ItemsControl HorizontalAlignment="Center" ItemsSource="{Binding MemoDtos}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <WrapPanel />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <!--自定义内容模板-->
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <md:TransitioningContent OpeningEffect="{md:TransitionEffect Kind=ExpandIn}">
                                    <!--自定义内容区域-->
                                    <Grid Width="220" MinHeight="180" MaxHeight="250" Margin="8" >
                                        <!--行为触发器-->
                                        <i:Interaction.Triggers>
                                            <!--鼠标左击事件-->
                                            <i:EventTrigger EventName="MouseLeftButtonUp">
                                                <!--设置命令-->
                                                <i:InvokeCommandAction 
                                                        CommandParameter="{Binding}"
                                                        Command="{Binding DataContext.SelectedCommand ,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}"/>
                                            </i:EventTrigger>
                                        </i:Interaction.Triggers>
                                        <!--定义2行-->
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="auto"/>
                                            <RowDefinition />
                                        </Grid.RowDefinitions>
                                        <!--右上角按钮-->
                                        <md:PopupBox HorizontalAlignment="Right" Panel.ZIndex="1">
                                            <Button Content="删除" CommandParameter="{Binding}"
                                             Command="{Binding DataContext.DeleteCommand ,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}"/>
                                        </md:PopupBox>

                                        <!--整个框圆角-->
                                        <Border CornerRadius="3" Grid.RowSpan="2" Background="#3CB371"/>

                                        <TextBlock  Text="{Binding Title}" Padding="10,5" FontWeight="Bold"/>
                                        <TextBlock Text="{Binding Content}" Padding="10,5" Grid.Row="1"/>
                                        <!--白色背景底色控件-->
                                        <Canvas Grid.RowSpan="2" ClipToBounds="True">
                                            <Border Canvas.Top="10" CornerRadius="100" Canvas.Right="-50" Width="120" Height="120" Background="#ffffff" Opacity="0.1"/>
                                            <Border Canvas.Top="80" CornerRadius="100" Canvas.Right="-30" Width="120" Height="120" Background="#ffffff" Opacity="0.1"/>
                                        </Canvas>
                                    </Grid>
                                </md:TransitioningContent>
                                
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </ScrollViewer>
                
            </Grid>

        </md:DrawerHost>

    </md:DialogHost>
</UserControl>

MemoViewModel.cs

namespace MyToDo.ViewModels
{
   public class MemoViewModel : NavigationViewModel
    {
        public MemoViewModel(IMemoService memoService, IContainerProvider provider) : base(provider)
        {
            MemoDtos = new ObservableCollection<MemoDto>();
            ExecuteCommand = new DelegateCommand<string>(Execute);
            SelectedCommand = new DelegateCommand<MemoDto>(Selected);
            DeleteCommand = new DelegateCommand<MemoDto>(Delete);
            this.memoService = memoService;
        }
        private bool isRightDrawerOpen;
        /// <summary>
        /// 右侧编辑窗口是否展开
        /// </summary>
        public bool IsRightDrawerOpen
        {
            get { return isRightDrawerOpen; }
            set { isRightDrawerOpen = value; RaisePropertyChanged(); }
        }
        private MemoDto currentDto;
        /// <summary>
        /// 编辑选中/新增对象
        /// </summary>
        public MemoDto CurrentDto
        {
            get { return currentDto; }
            set { currentDto = value; RaisePropertyChanged(); }
        }

        private string search;
        /// <summary>
        /// 用户输入的搜索条件
        /// </summary>
        public string Search
        {
            get { return search; }
            set { search = value; RaisePropertyChanged(); }
        }

        public DelegateCommand<string> ExecuteCommand { get; private set; }
        public DelegateCommand<MemoDto> SelectedCommand { get; private set; }
        public DelegateCommand<MemoDto> DeleteCommand { get; private set; }
        private ObservableCollection<MemoDto> memoDtos;
        private readonly IMemoService memoService;

        /// <summary>
        /// 创建数据的动态集合
        /// </summary>
        public ObservableCollection<MemoDto> MemoDtos
        {
            get { return memoDtos; }
            set { memoDtos = value; RaisePropertyChanged(); }
        }
        async  void GetDataAsync()
        {
            UpdateLoading(true); //发布消息,设置加载中的窗口
            var memoResult= await memoService.GetAllAsync(new Shared.Parameters.QueryParameter()
            {
                PageIndex = 0,
                PageSize = 100,
                Search= Search
            });
            if (memoResult.Status)
            {
                memoDtos.Clear();
                foreach (var item in memoResult.Result.Items)
                {
                    memoDtos.Add(item);
                }
            }
            UpdateLoading(false); //发布消息,关闭加载中的窗口
            //for (int i = 0; i < 20; i++)
            //{
            //    memoDtos.Add(new MemoDto()
            //    {
            //        Title = "标题" + i,
            //        Content = "测试数据..."
            //    });
            //}
        }
        /// <summary>
        /// 添加备忘录
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void Add()
        {
            CurrentDto = new MemoDto();//添加时,初始化一个新对象
            IsRightDrawerOpen = true;
        }
        private async void Save()
        {
            //判断数据是否为空
            if (string.IsNullOrWhiteSpace(CurrentDto.Title) || string.IsNullOrWhiteSpace(CurrentDto.Content)) return;
            UpdateLoading(true);
            try
            {
                if (CurrentDto.Id > 0) //Id 大于0,表示编辑。否则新增
                {
                    var updateResult = await memoService.UpdateAsync(CurrentDto);
                    if (updateResult.Status) //更新成功
                    {
                        //查找到当前界面更新的那个条数据,把显示的内容进行更新
                        var todo = memoDtos.FirstOrDefault(t => t.Id == CurrentDto.Id);
                        if (todo != null)
                        {
                            todo.Title = CurrentDto.Title;
                            todo.Content = CurrentDto.Content;
                        }
                        IsRightDrawerOpen = false; //关闭编辑窗口
                    }
                }
                else
                {

                    var addResult = await memoService.AddAsync(CurrentDto);
                    if (addResult.Status)
                    {
                        if (addResult.Result != null)
                        {
                            memoDtos.Add(addResult.Result); //把数据添加到界面的集合中
                            IsRightDrawerOpen = false; //关闭新增窗口
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                await Console.Out.WriteLineAsync(ex.Message);
            }
            finally
            {
                UpdateLoading(false);
            }
        }
        private async void Delete(MemoDto dto)
        {
            try
            {
                UpdateLoading(true); //发布消息,设置加载中的窗口
                var deleteResult = await memoService.DeleteAsync(dto.Id);
                if (deleteResult.Status)
                {
                    //在当前数据集合中,找到当前已经删除掉的数据,并移除掉
                    var model = memoDtos.FirstOrDefault(t => t.Id.Equals(dto.Id));
                    if (model != null) memoDtos.Remove(model);
                }
            }
            catch (Exception ex)
            {
                await Console.Out.WriteLineAsync(ex.Message);
            }
            finally
            {
                UpdateLoading(false); //发布消息,关闭加载中的窗口
            }
        }
        /// <summary>
        /// 根据不同的参数,处理不同的逻辑
        /// </summary>
        /// <param name="obj"></param>
        private void Execute(string obj)
        {
            switch (obj)
            {
                case "新增":
                    Add();
                    break;
                case "查询":
                    GetDataAsync();
                    break;
                case "保存":
                    Save();
                    break;
            }
        }
        private async void Selected(MemoDto obj)
        {
            try
            {
                UpdateLoading(true);

                //进行数据查询
                var todoResult = await memoService.GetFirstOfDefaultAsync(obj.Id);
                if (todoResult.Status)
                {
                    //把拿到的结果,赋给一个当前选中的ToDoDto
                    CurrentDto = todoResult.Result;
                    IsRightDrawerOpen = true;//打开窗口
                }
            }
            catch (Exception ex)
            {
                await Console.Out.WriteLineAsync(ex.Message);
            }
            finally
            {
                UpdateLoading(false);
            }

        }
        //重写导航加载数据的方法
        public override void OnNavigatedTo(NavigationContext navigationContext)
        {
            base.OnNavigatedTo(navigationContext);
            GetDataAsync();
        }
    }
}

二.错误排查

如果有出现相关的错误,例如,查询异常或其他其他。直接参考上一章节的错误排查就好了。

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

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

相关文章

用html写一个搜索页面

<!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>搜索框设计</title><link rel"stylesheet" href"./style.css"> </head> <body> <div class"se…

TypeScript基础入门(一、常用类型)

目录 第一章 前言 1.1 介绍TypeScript 1.2 TypeScript相比Js的优势 1.3 使用TypeScript的准备工作 第二章 TypeScript的数据类型 2.1 TypeScript的常用类型 2.1.1 概述 2.1.2 TS使用JS基本数据类型 2.1.2.1 number 2.1.2.2 string 2.1.3.3 boolean 2.1.2.4 null 2…

Pytorch DistributedDataParallel(DDP)教程一:快速入门理论篇

Pytorch DistributedDataParallel&#xff08;DDP&#xff09;教程一&#xff1a;快速入门理论篇 目录 一、 写在前面二、什么是分布式并行训练1. 并行训练2. 数据并行 三、DDP的基本原理1. DDP的训练过程2. Ring-All-Reduce算法 四、如何搭建一个Pytorch DDP代码框架1. 与DDP有…

二次元AI绘画生成器免费:教你生成精美图片

二次元AI绘画生成器&#xff0c;无疑是现代技术与艺术完美结合的典范。这些工具不仅将复杂的绘画过程简化&#xff0c;更让每一个艺术爱好者的创意得以充分展现。这些生成器能够精准捕捉大家的创意精髓&#xff0c;将其转化为细腻、独特的二次元画作。无论是角色设计、场景描绘…

OpenHarmony UI动画-box2d

简介 用于游戏开发&#xff0c;使物体的运动更加真实&#xff0c;让游戏场景看起来更具交互性&#xff0c;比如愤怒的小鸟 效果展示 下载安装 ohpm install ohos/box2dOpenHarmony ohpm环境配置等更多内容&#xff0c;请参考 如何安装OpenHarmony ohpm包 使用说明 import * …

OCR图片转化为Excel文件功能在哪些平台和设备上能实现?

在现今数字化时代&#xff0c;将图片转化为Excel文件已成为许多工作者和研究者的重要需求。这种转换功能在多个平台和设备上均能实现&#xff0c;为用户提供了极大的便利。 首先&#xff0c;我们来看看在线平台方面。目前&#xff0c;市面上有许多在线工具可以将图片转换为Exc…

MoJoCo 入门教程(七)XML 参考

系列文章目录 前言 表格第二列中的符号含义如下&#xff1a; ! 必填元素&#xff0c;只能出现一次 ? 可选元素&#xff0c;只能出现一次 * 可选元素&#xff0c;可多次出现 R 可选元素&#xff0c;可递归出现多次 一、简介 本章是 MuJoCo 中使用的 MJCF 建模语言的参考手册。…

【云计算】安全组和网络ACL的区别

安全组和网络ACL的区别 ACL&#xff08;Access Control List&#xff09;和 安全组&#xff08;Security Group&#xff09;是两种不同的网络安全控制机制&#xff0c;通常用于管理云计算平台中的网络访问权限。它们在功能和实现上有一些显著的区别&#xff1a; 辨析 范围不同&…

如何把网易云ncm转换为mp3格式

大家在网易云下载音乐的时候会发现下载的音乐格式是ncm&#xff0c;这个格式只能在网易云播放器才能播放&#xff0c;无法在别的播放器上播放。今天教大家把ncm转换为更加通用的格式 打开智游剪辑&#xff08;官网: zyjj.cc&#xff09;&#xff0c;搜索ncm转mp3 这里就只需要上…

DC电源模块的未来发展方向和创新应用领域

BOSHIDA DC电源模块的未来发展方向和创新应用领域 随着科技的快速发展&#xff0c;直流&#xff08;DC&#xff09;电源模块的应用领域也在不断扩大。从传统的电子产品到新兴的清洁能源领域&#xff0c;DC电源模块正发挥着越来越重要的作用。未来&#xff0c;DC电源模块将继续…

windows docker desktop==spark环境搭建

编写文件docker-compose.yml version: 3services:spark-master:image: bde2020/spark-master:3.1.1-hadoop3.2container_name: spark-masterports:- "8080:8080"- "7077:7077"- "2220:22"volumes:- F:\spark-data\m1:/dataenvironment:- INIT_D…

android studio gradle 下载不下来的问题

有时候由于网络问题&#xff0c;会发现 android-studio 或 idea 下载不懂 gradle&#xff0c;可以修改 gradle-wrapper.properties 配置文件中的 distributionUrl 选项来解决这个问题。 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-5.1.1-all.zip 这个选…

【七 (2)FineBI FCP模拟试卷-平台新增用户留存分析】

目录 文章导航一、字段解释1、用户平台登录信息表格2、用户平台激活信息表格 二、需求三、操作步骤1、建立用户平台登录信息表格和用户平台激活信息表格的关联关系2、将用户平台激活信息表格的激活日期添加到用户平台登录信息表格3、新增公式列&#xff0c;计算激活时间和登录时…

【ACM列表推荐会议 | EI稳定检索】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于20…

JVM虚拟机(十)Java内存泄漏的排查思路

目录 一、可能产生内存泄露的地方二、复现堆内存泄漏三、如何排查堆内存问题&#xff1f;3.1 获取对内存快照 dump3.2 使用 Visual VM 去分析 dump 文件3.3 定位内存溢出问题 一、可能产生内存泄露的地方 在进行排查 Java 的内存泄漏问题之前&#xff0c;首先我们要知道哪里可…

数据可视化-ECharts Html项目实战(12)

在之前的文章中&#xff0c;我们深入学习ECharts特殊图表中的矩形树图以及Echarts中高级功能的多图表联动。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 数…

通过IP地理位置阻止网络攻击:有效性与局限性

网络攻击已成为当今互联网世界中的一项常见挑战。黑客和恶意用户利用各种手段对网络系统进行攻击&#xff0c;造成数据泄露、服务中断甚至财产损失。在这种背景下&#xff0c;寻找有效的网络安全解决方案变得至关重要。 IP地理位置阻止是一种基于黑名单的网络安全措施。它的原…

最新SpringBoot项目财务管理系统

采用技术 最新SpringBoot项目财务管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 系统登录页面 管理员功能 管理员功能页面 员工管理页面 部…

Python采集海外电影信息,Roxlabs全球IP代理轻松搞定

一、为什么要学会应用 IP 代理技术二、采集海外电影信息爬虫实战2.1 选择目标网站并生成代理2.2 编写爬虫并设置代理2.3 运行爬虫2.4 处理数据2.5 完整代码 三、Roxlabs 代理及优势分析四、快速应用Roxlabs代理功能4.1 领免费流量4.2 代理类型4.3 获取代理4.4 配置代理设置4.5 …

进销存是什么?怎么快速上手制作进销存报表?

在现代商业运营中&#xff0c;进销存管理是企业持续稳健发展的关键组成部分。为了更好地把握库存状况、合理调配资源、提高决策效率&#xff0c;企业采用进销存报表是一种极为有效的手段。本文将从进销存的基本概念、报表的内容和意义&#xff0c;以及如何制作进销存报表等方面…