Wpf 使用 Prism 实战开发Day20

时间:2024-04-23 08:27:21

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

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

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

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();
        }
    }
}

二.错误排查

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