Wpf 使用 Prism 实战开发Day27

首页汇总和数据动态显示

一.创建首页数据汇总数据接口

  • 汇总:待办事项的总数
  • 已完成:待办事项里面有多少条完成的待办
  • 完成比例:已完成和汇总之间的比例
  • 备忘录:显示备忘录的总数
  • 待办事项:显示待办事项未完成的集合
  • 备忘录:显示全部的备忘录信息

step1:在MyToDo.Shared 项目中创建出首页汇总的数据实体类(SummaryDto)

cs 复制代码
public class SummaryDto:BaseDto
{
	private int sum;
	/// <summary>
	/// 汇总
	/// </summary>
	public int Sum
	{
		get { return sum; }
		set { sum = value;OnPropertyChanged();}
	}
	private int completedCount;
	/// <summary>
	/// 已完成总数
	/// </summary>
	public int CompletedCount
    {
		get { return completedCount; }
		set { completedCount = value; OnPropertyChanged(); }
	}
	private string completedRatio;
	/// <summary>
	/// 完成比例
	/// </summary>
	public string CompletedRatio
    {
		get { return completedRatio; }
		set { completedRatio = value; OnPropertyChanged(); }
	}
	private int memoeCount;
	/// <summary>
	/// 备忘录总数
	/// </summary>
	public int MemoeCount
    {
		get { return memoeCount; }
		set { memoeCount = value; OnPropertyChanged(); }
	}


	private ObservableCollection<ToDoDto> todoList;
	/// <summary>
	/// 待办事项列表
	/// </summary>
	public ObservableCollection<ToDoDto> TodoList
	{
		get { return todoList; }
		set { todoList = value; OnPropertyChanged(); }
	}
    private ObservableCollection<MemoDto> memoList;
    /// <summary>
    /// 备忘录列表
    /// </summary>
    public ObservableCollection<MemoDto> MemoList
    {
        get { return memoList; }
        set { memoList = value; OnPropertyChanged(); }
    }
}

step2:在MyToDo.Api 项目中,创建接口实现

1.在IToDoService 增加汇总接口
cs 复制代码
    public interface IToDoService: IBaseService<ToDoDto>
    {
        Task<ApiResponse> GetAllFilterAsync(ToDoParameter query);
        /// <summary>
        /// 汇总接口
        /// </summary>
        /// <returns></returns>
        Task<ApiResponse> Summary();
    }
2.ToDoService 实现汇总接口逻辑
cs 复制代码
 public async Task<ApiResponse> Summary()
 {
     try
     {
         //待办事项结果
         var todos = await work.GetRepository<ToDo>().GetAllAsync(orderBy: source => source.OrderByDescending(t => t.CreateDate));
         //备忘录结果
         var memos = await work.GetRepository<Memo>().GetAllAsync(orderBy: source => source.OrderByDescending(m => m.CreateDate));

         SummaryDto summary = new SummaryDto();
         summary.Sum = todos.Count();//汇总待办事项数量
         summary.CompletedCount = todos.Where(t => t.Status == 1).Count();//统计待办完成数量
         summary.CompletedRatio = (summary.CompletedCount / (double)summary.Sum).ToString("0%");//统计完成比率,转换成百分比
         summary.MemoeCount = memos.Count();//备忘录总数
         summary.TodoList = new ObservableCollection<ToDoDto>(mapper.Map<List<ToDoDto>>(todos.Where(t => t.Status == 0))); //未完成的待办
         summary.MemoList = new ObservableCollection<MemoDto>(mapper.Map<List<MemoDto>>(memos));
         return new ApiResponse(true, summary);
     }
     catch (Exception ex)
     {
         return new ApiResponse(false,ex.Message);
     }
 }

step3:在MyToDo.Api 项目中,ToDoController 控制器层添加请求方式供外部调用


二.数据接口创建完成后,客户端中去使用该接口

step1:首先在MyToDo 项目中的Server层,IToDoService 中增加一个汇总接口

step 2:在ToDoService 中实现上面的接口,获取统计汇总的数据


step3:在首页IndexViewModel 中去调用该接口,获取数据

1.首先,创建一个 SummaryDto,去接收调用接口传过来的数据
cs 复制代码
        private SummaryDto summaryDto;

        public SummaryDto SummaryDto
        {
            get { return summaryDto; }
            set { summaryDto = value; RaisePropertyChanged(); }
        }
2. 重写导航事件方法 OnNavigatedTo,在该方法中调用汇总接口。拿到数据后赋给当前SummaryDto
cs 复制代码
public override  void OnNavigatedTo(NavigationContext navigationContext)
{
    GetSummaryAsync();
    base.OnNavigatedTo(navigationContext);
}
/// <summary>
/// 获取汇总数据
/// </summary>
async void GetSummaryAsync()
{
    var summaryResult = await toDoService.SummaryAsync();
    if (summaryResult.Status)
    {
        SummaryDto = summaryResult.Result;
        RefreshBars();
    }
}
3.修改统计列表数据中的Content赋值。需要动态从接口中获取,并动态赋值。

在TaskBars中的Content属性,要调用实现通知绑定方法 RaisePropertyChanged

cs 复制代码
void RefreshBars()
{
    TaskBars[0].Content = summaryDto.Sum.ToString();
    TaskBars[1].Content = summaryDto.CompletedCount.ToString();
    TaskBars[2].Content = summaryDto.CompletedRatio;
    TaskBars[3].Content = summaryDto.MemoeCount.ToString();
}
4.由于SummaryDto 已经拿到待办事项和备忘录的所有数据了,接下来修改整个IndexViewMode,把单独显示ToDoDtos和MemoDtos数据集合全部删掉,改成通过SummaryDto 来获取待办或备忘录数据。并且前端视图也要修改去拿数据的对应数据集合。

IndexViewModel 完整代码

cs 复制代码
public class IndexViewModel:NavigationViewModel
{
    private readonly IToDoService toDoService;
    private readonly IMemoService memoService;
    public IndexViewModel(IDialogHostService dialogService,IContainerProvider provider):base(provider)
    {
        TaskBars=new ObservableCollection<TaskBar>();
        ExecuteCommand = new DelegateCommand<string>(Execute);
        EditTodoCommand = new DelegateCommand<ToDoDto>(AddTodo);
        EditMemoCommand = new DelegateCommand<MemoDto>(AddMemo);
        ToDoCompltedCommand = new DelegateCommand<ToDoDto>(Complted);
        CreateTaskBars();
        this.toDoService = provider.Resolve<IToDoService>();//取到待办事项接口服务实例
        this.memoService = provider.Resolve<IMemoService>();
        this.dialogService = dialogService;
    }
    public DelegateCommand<ToDoDto> ToDoCompltedCommand {  get; private set; }//完成按钮绑定命令
    public DelegateCommand<ToDoDto> EditTodoCommand { get; private set; } //待办事项双击绑定命令
    public DelegateCommand<MemoDto> EditMemoCommand { get; private set; } //备忘录双击绑定命令
    
    public DelegateCommand<string> ExecuteCommand { get; private set; }
        
    private ObservableCollection<TaskBar> taskBars;

    public ObservableCollection<TaskBar> TaskBars
    {
        get { return taskBars; }
        set { taskBars = value; RaisePropertyChanged(); }
    }
    private readonly IDialogHostService dialogService;
    private SummaryDto summaryDto;
    /// <summary>
    /// 首页统计
    /// </summary>
    public SummaryDto SummaryDto
    {
        get { return summaryDto; }
        set { summaryDto = value; RaisePropertyChanged(); }
    }

    void CreateTaskBars()
    {
        TaskBars.Add(new TaskBar() { Icon="ClockFast",Title="汇总",Color="#FF0CA0FF",Target=""});
        TaskBars.Add(new TaskBar() { Icon = "ClockCheckOutline", Title = "已完成", Color = "#FF1ECA3A", Target = "" });
        TaskBars.Add(new TaskBar() { Icon = "ChartLineVariant", Title = "完成比例", Color = "#FF02C6DC", Target = "" });
        TaskBars.Add(new TaskBar() { Icon = "PlaylistStar", Title = "备忘录", Color = "#FFFFA000", Target = "" });
    }
    void RefreshBars()
    {
        TaskBars[0].Content = summaryDto.Sum.ToString();
        TaskBars[1].Content = summaryDto.CompletedCount.ToString();
        TaskBars[2].Content = summaryDto.CompletedRatio;
        TaskBars[3].Content = summaryDto.MemoeCount.ToString();
    }
    
    public override  void OnNavigatedTo(NavigationContext navigationContext)
    {
        GetSummaryAsync();
        base.OnNavigatedTo(navigationContext);
    }
    /// <summary>
    /// 获取汇总数据
    /// </summary>
    async void GetSummaryAsync()
    {
        var summaryResult = await toDoService.SummaryAsync();
        if (summaryResult.Status)
        {
            SummaryDto = summaryResult.Result;
            RefreshBars();
        }
    }
    private void Execute(string obj)
    {
       switch(obj)
        {
            case "新增备忘录":
                AddMemo();
                break;
            case "新增待办事项":
                AddTodo();
                break;
        }
    }
    async void AddMemo(MemoDto? model =null)
    {
        DialogParameters param = new DialogParameters();
        if (model != null)//如果是编辑
        {
            param.Add("Value",model);//把要编辑的数据传过去
        }
        var dialogMemoResult = await dialogService.ShowDialog("AddMemoView", param, "RootDialog");
        if (dialogMemoResult.Result == ButtonResult.OK)
        {
            UpdateLoading(true);
            var memo = dialogMemoResult.Parameters.GetValue<MemoDto>("Value");//获取到弹窗传过来的值
            if (memo.Id > 0)//编辑
            {
                var updateResult = await memoService.UpdateAsync(memo);
                if (updateResult.Status)//更新成功
                {
                    var memoModel = SummaryDto.MemoList.FirstOrDefault(it => it.Id.Equals(memo.Id));//在界面的数据集合中,找到要更新的那条数据
                    if (memoModel != null)
                    {
                        memoModel.Title = memo.Title;
                        memoModel.Content = memo.Content;
                    }
                }
            }
            else
            {
                //新增
                var addResult = await memoService.AddAsync(memo);
                if (addResult.Status)
                {
                    SummaryDto.MemoList.Add(addResult.Result);//添加到界面的集合中
                }
            }
            GetSummaryAsync();
            UpdateLoading(false);
        }
    }
    async void AddTodo(ToDoDto? model = null)
    {
        DialogParameters param = new DialogParameters();
        if (model != null)//如果是编辑
        {
            param.Add("Value", model);//把要编辑的数据传过去
        }
        var dialogToDoResult = await dialogService.ShowDialog("AddToDoView", param, "RootDialog");
        if (dialogToDoResult.Result == ButtonResult.OK)
        {
            UpdateLoading(true);
            var todo = dialogToDoResult.Parameters.GetValue<ToDoDto>("Value");//获取到弹窗传过来的值
            if (todo.Id > 0)//编辑
            {
               var updateResult=await toDoService.UpdateAsync(todo);
                if(updateResult.Status)//更新成功
                {
                   var todoModel= SummaryDto.TodoList.FirstOrDefault(it => it.Id.Equals(todo.Id));//在界面的数据集合中,找到要更新的那条数据
                    if (todoModel != null)
                    {
                        todoModel.Title = todo.Title;
                        todoModel.Content= todo.Content;
                    }
                }
            }
            else
            {
                //新增
                var addResult = await toDoService.AddAsync(todo);
                if (addResult.Status)
                {
                    SummaryDto.TodoList.Add(addResult.Result);//添加到界面的集合中
                }
            }
            GetSummaryAsync();
            UpdateLoading(false);
        }
    }

    private async void Complted(ToDoDto dto)
    {
       var updateResult=await toDoService.UpdateAsync(dto);//根据传过来的对象进行更新
        if(updateResult.Status)
        {
           var todo= SummaryDto.TodoList.FirstOrDefault(t=>t.Id.Equals(dto.Id));//在界面数据列表中找到这条数据
           if(todo != null)
            {
                SummaryDto.TodoList.Remove(todo);
                GetSummaryAsync();
            }
        }
    }
}

IndexView完整代码

cs 复制代码
<UserControl x:Class="MyToDo.Views.IndexView"
             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:i="http://schemas.microsoft.com/xaml/behaviors"
             xmlns:cv="clr-namespace:MyToDo.Common.Converters"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <cv:IntToBoolConveter x:Key="intToBool"/>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Margin="15,10" FontSize="22" Text="你好,WPF! 今天是2023-11-12 星期天"/>

        <ItemsControl Grid.Row="1" ItemsSource="{Binding TaskBars}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="4"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <!--模板内容设计-->
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border Background="{Binding Color}" CornerRadius="5" Margin="10">
                        <Border.Style>
                            <Style TargetType="Border">
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Effect">
                                            <Setter.Value>
                                                <DropShadowEffect Color="#DDDDDD" ShadowDepth="1" BlurRadius="10" />
                                            </Setter.Value>
                                        </Setter>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                        <Grid>
                            <StackPanel Margin="20,10">
                                <!--图标-->
                                <materialDesign:PackIcon Kind="{Binding Icon}" Width="30" Height="30" />
                                <!--标题文本-->
                                <TextBlock Text="{Binding Title}" Margin="0,15" FontSize="15"/>
                                <!--内容-->
                                <TextBlock Text="{Binding Content}" FontWeight="Bold" FontSize="40"/>
                            </StackPanel>
                            <!--白色背景底色控件-->
                            <Canvas 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>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <Grid Grid.Row="2" Margin="0,10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
             
            <!--外边框-->
            <Border Margin="10,0" Background="#BEBEBE" CornerRadius="5" Opacity="0.1"/>
            <Border Grid.Column="1" Margin="10,0" Background="#BEBEBE" CornerRadius="5" Opacity="0.1"/>
            
            <!--主体内容左-->
            <DockPanel Margin="10,0">
                <DockPanel Margin="10,5" LastChildFill="False" DockPanel.Dock="Top">
                    <TextBlock Text="待办事项" FontSize="20" FontWeight="Bold"/>
                    <Button Width="30" Height="30" VerticalAlignment="Top" DockPanel.Dock="Right" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" 
                            Command="{Binding ExecuteCommand}" CommandParameter="新增待办事项">
                        <materialDesign:PackIcon Kind="Add" />
                    </Button>
                </DockPanel>
                <!--数据列表区域-->
                <ListBox x:Name="todoList" ItemsSource="{Binding SummaryDto.TodoList}" ScrollViewer.VerticalScrollBarVisibility="Hidden" HorizontalContentAlignment="Stretch" >
                    <!--鼠标双击-->
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseDoubleClick">
                            <i:InvokeCommandAction  Command="{Binding EditTodoCommand}"
                                                    CommandParameter="{Binding ElementName=todoList,Path=SelectedItem}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <DockPanel MaxHeight="80" LastChildFill="False">
                                <ToggleButton DockPanel.Dock="Right" Command="{Binding DataContext.ToDoCompltedCommand,
                                     RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}" IsChecked="{Binding Status,Converter={StaticResource intToBool}}"
                                              CommandParameter="{Binding}"/>
                                <StackPanel>
                                    <TextBlock Text="{Binding Title}" FontSize="16" FontWeight="Bold"/>
                                    <TextBlock Text="{Binding Content}" Margin="0,5" Opacity="0.5" />
                                </StackPanel>
                            </DockPanel>
                           
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DockPanel>

            <!--主体内容右-->
            <DockPanel  Grid.Column="1" Margin="10,0">
                <DockPanel Margin="10,5" LastChildFill="False" DockPanel.Dock="Top">
                    <TextBlock Text="备忘录" FontSize="20" FontWeight="Bold"/>
                    <Button Width="30" Height="30" VerticalAlignment="Top" DockPanel.Dock="Right" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" 
                            Command="{Binding ExecuteCommand}" CommandParameter="新增备忘录">
                        <materialDesign:PackIcon Kind="Add" />
                    </Button>
                </DockPanel>
                <!--数据列表区域-->
                <ListBox x:Name="memoList"  ItemsSource="{Binding SummaryDto.MemoList}"  ScrollViewer.VerticalScrollBarVisibility="Hidden" >
                    <!--鼠标双击-->
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseDoubleClick">
                            <i:InvokeCommandAction  Command="{Binding EditMemoCommand}"
                                CommandParameter="{Binding ElementName=memoList,Path=SelectedItem}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel MaxHeight="80">
                                <TextBlock Text="{Binding Title}" FontSize="16" FontWeight="Bold"/>
                                <TextBlock Text="{Binding Content}" Margin="0,5" Opacity="0.5" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DockPanel>
        </Grid>
    </Grid>
</UserControl>
相关推荐
IT技术分享社区8 分钟前
C#实战:使用腾讯云识别服务轻松提取火车票信息
开发语言·c#·云计算·腾讯云·共识算法
月落.1 小时前
WPF的<ContentControl>控件
wpf
就是有点傻1 小时前
WPF中的依赖属性
开发语言·wpf
wangnaisheng1 小时前
【WPF】把一个Window放在左上角/右上角顶格显示
wpf
WineMonk1 小时前
.NET WPF CommunityToolkit.Mvvm框架
.net·wpf·mvvm
月落.1 小时前
WPF中的INotifyPropertyChanged接口
wpf
界面开发小八哥1 小时前
界面控件DevExpress WPF中文教程:Data Grid——卡片视图设置
.net·wpf·界面控件·devexpress·ui开发
平凡シンプル1 小时前
WPF 打包
wpf
wrx繁星点点1 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
VickyJames2 小时前
基于XAML框架和跨平台项目架构设计的深入技术分析
wpf·开源分享·unoplatform·winui3·项目架构