循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(4) -- 实现DataGrid数据的导入和导出操作

简介: 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(4) -- 实现DataGrid数据的导入和导出操作

在我们设计软件的很多地方,都看到需要对表格数据进行导入和导出的操作,主要是方便客户进行快速的数据处理和分享的功能,本篇随笔介绍基于WPF实现DataGrid数据的导入和导出操作。

1、系统界面设计

在我们实现数据的导入导出功能之前,我们在主界面需要提供给客户相关的操作按钮,如下界面所示,在列表的顶端提供导入Excel、导出PDF、导出Excel。

由于这些操作功能基本上在各个页面模块,可能都会用到,因此尽可能的抽象到基类,以及提供通用的处理操作,实在有差异的,也可以通过一些属性或者事件方法的覆盖方式来实现即可。

因此我们在Xaml里面定义按钮的时候,基本上是调用视图模型的方法来通用化的处理,如下代码所示。

<Button
    Margin="5"
    hc:IconElement.Geometry="{StaticResource t_import}"
    Command="{Binding ImportExcelCommand}"
    Content="导入Excel"
    Style="{StaticResource ButtonWarning}" />
<Button
    Margin="5"
    hc:IconElement.Geometry="{StaticResource SaveGeometry}"
    Command="{Binding ViewModel.ExportPdfCommand}"
    CommandParameter="用户信息列表"
    Content="导出PDF"
    Style="{StaticResource ButtonSuccess}" />
<Button
    Margin="5"
    hc:IconElement.Geometry="{StaticResource SaveGeometry}"
    Command="{Binding ViewModel.ExportExcelCommand}"
    CommandParameter="用户信息列表"
    Content="导出Excel"
    Style="{StaticResource ButtonSuccess}" />

而导入的处理操作函数ImportExcelComand的定义如下所示(注意这里声明了RelayCommand)代码会自动生成Command的后缀Command方法的。

/// <summary>
    /// 导出内容到Excel
    /// </summary>
    [RelayCommand]
    private void ImportExcel()
    {
        var page = App.GetService<ImportExcelData>();
        page!.ViewModel.Items?.Clear();
        page!.ViewModel.TemplateFile = $"系统用户信息-模板.xls";
        page!.OnDataSave -= ExcelData_OnDataSave;
        page!.OnDataSave += ExcelData_OnDataSave;
        //导航到指定页面
        ViewModel.Navigate(typeof(ImportExcelData));
    }

而其中 ImportExcelData 是我们定义的通用导入页面窗体类,这里只需要实现一些属性的设置(根据子类的不同而调整,后期可以用代码生成工具生成),以及一些事件用于子类延后实现,从而可以实现自定义的数据处理的功能。

我们在下面再细说批量导入的处理细节。

 

2、数据导出到Excel

数据导出到Excel,在我们的Winform端中很常见,而WPF这里也是一样的处理方式,通用利用Excel的操作组件的封装类来实现,可以基于NPOI,也可以基于Aspose.Cell实现,根据自己的需要实现简单的封装调用即可。

导出到Excel,首先需要弹出选择目录的对话框进行选取目录,然后用于生成Excel的文件,如下界面所示。

这个处理,由于WPF可以调用.net里面的System.Windows.Forms,因此我们直接调用里面的对话框处理封装即可,这个类来自于我们的Winform的UI公用类库部分。

在前面随笔,我们介绍过为了WPF开发的方便,我们设计了几个视图基类,用于减少代码的处理。

对于不同的业务类,我们也只需要根据实际情况,生成对应的业务视图模型类即可。

我们把通用的导出操作放到了这个视图基类BaseListViewModel 里面即可,如下代码所示。

/// <summary>
/// 触发导出Excel处理命令
/// </summary>
[RelayCommand]
protected virtual async Task ExportExcel(string title = "列表数据")
{
    var table = await this.ConvertItems(this.Items);
    BaseExportExcel(table, title);
}

而其中对于DataTable的处理Excel,提供一个通用的方法。

/// <summary>
    /// 可供重写的基类函数,导出Excel
    /// </summary>
    public virtual void BaseExportExcel(DataTable table, string title = "列表数据")
    {
        string file = FileDialogHelper.SaveExcel(string.Format("{0}.xls", title));
        if (!string.IsNullOrEmpty(file))
        {
            try
            {
                string error = "";
                AsposeExcelTools.DataTableToExcel2(table, file, out error);
                if (!string.IsNullOrEmpty(error))
                {
                    MessageDxUtil.ShowError(string.Format("导出Excel出现错误:{0}", error));
                }
                else
                {
                    if (MessageDxUtil.ShowYesNoAndTips("导出成功,是否打开文件?") == System.Windows.MessageBoxResult.Yes)
                    {
                        Process.Start("explorer.exe", file);
                    }
                }
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                MessageDxUtil.ShowError(ex.Message);
            }
        }
    }

其中FileDialogHelper.SaveExcel 的代码如下所示。

/// <summary>
/// 保存Excel对话框,并返回保存全路径
/// </summary>
/// <returns></returns>
public static string SaveExcel(string filename, string initialDirectory)
{
    return Save("保存Excel", ExcelFilter, filename, initialDirectory);
} 
/// <summary>
/// 以指定的标题弹出保存文件对话框
/// </summary>
/// <param name="title">对话框标题</param>
/// <param name="filter">后缀名过滤</param>
/// <param name="filename">默认文件名</param>
/// <param name="initialDirectory">初始化目录</param>
/// <returns></returns>
public static string Save(string title, string filter, string filename, string initialDirectory)
{
    //多语言支持
    title = JsonLanguage.Default.GetString(title);
    var dialog = new SaveFileDialog();
    dialog.Filter = filter;
    dialog.Title = title;
    dialog.FileName = filename;
    dialog.RestoreDirectory = true;
    if (!string.IsNullOrEmpty(initialDirectory))
    {
        dialog.InitialDirectory = initialDirectory;
    }
    if (dialog.ShowDialog() == DialogResult.OK)
    {
        return dialog.FileName;
    }
    return string.Empty;
}

而其中SaveFileDialog是属于.net 中System.Windows.Forms里面的内容,WPF可以直接调用。

而DataTableToExcel2 方法,这是我们封装的一个使用Aspose.Cell的调用,主要用于快速处理DataTable到Excel的操作封装,我们也可可以利用其它操作Excel的封装,如NPOI等都可以实现。

代码如下所示。

/// <summary>
/// 把DataTabel转换成Excel文件
/// </summary>
/// <param name="datatable">DataTable对象</param>
/// <param name="filepath">目标文件路径,Excel文件的全路径</param>
/// <param name="error">错误信息:返回错误信息,没有错误返回""</param>
/// <returns></returns>
public static bool DataTableToExcel2(DataTable datatable, string filepath, out string error)
{
    error = "";
    var wb = new Aspose.Cells.Workbook();
    try
    {
        if (datatable == null)
        {
            error = "DataTableToExcel:datatable 为空";
            return false;
        }
        //为单元格添加样式    
        var style = wb.CreateStyle();
        //设置居中
        style.HorizontalAlignment = Aspose.Cells.TextAlignmentType.Center;
        //设置背景颜色
        style.ForegroundColor = System.Drawing.Color.FromArgb(153, 204, 0);
        style.Pattern = BackgroundType.Solid;
        style.Font.IsBold = true;
        int rowIndex = 0;
        for (int i = 0; i < datatable.Columns.Count; i++)
        {
            DataColumn col = datatable.Columns[i];
            string columnName = col.Caption ?? col.ColumnName;
            wb.Worksheets[0].Cells[rowIndex, i].PutValue(columnName);
            wb.Worksheets[0].Cells[rowIndex, i].SetStyle(style);
        }
        rowIndex++;
        foreach (DataRow row in datatable.Rows)
        {
            for (int i = 0; i < datatable.Columns.Count; i++)
            {
                wb.Worksheets[0].Cells[rowIndex, i].PutValue(row[i].ToString());
            }
            rowIndex++;
        }
        for (int k = 0; k < datatable.Columns.Count; k++)
        {
            wb.Worksheets[0].AutoFitColumn(k, 0, 150);
        }
        wb.Worksheets[0].FreezePanes(1, 0, 1, datatable.Columns.Count);
        wb.Save(filepath);
        return true;
    }
    catch (Exception e)
    {
        error = error + " DataTableToExcel: " + e.Message;
        return false;
    }
}

导出Excel的内容如下界面所示。另外导出文档的内容,我们可以用于导入的数据模板的。

我们可以根据需要设置要导出的列即可。

 

3、数据导出到PDF

同样,数据导出到PDF的处理操作类似,也是通过视图基类的封装方法,实现快速的导出到PDF处理,如下是视图基类里面的实现方法。

/// <summary>
/// 触发导出PDF处理命令
/// </summary>
[RelayCommand]
protected virtual async Task ExportPdf(string title = "列表数据")
{
    var table = await this.ConvertItems(this.Items);
    BaseExportPdf(table, title);
}
/// <summary>
/// 可供重写的基类函数,导出PDF
/// </summary>
public virtual void BaseExportPdf(DataTable table, string title = "列表数据")
{
    var pdfFile = FileDialogHelper.SavePdf();
    if (!pdfFile.IsNullOrEmpty())
    {
        bool isLandscape = true;//是否为横向打印,默认为true
        bool includeHeader = true;//是否每页包含表头信息
        var headerAlignment = iText.Layout.Properties.HorizontalAlignment.CENTER;//头部的对其方式,默认为居中
        float headerFontSize = 9f;//头部字体大小
        float rowFontSize = 9f;//行记录字体大小
        float? headerFixHeight = null;//头部的固定高度,否则为自适应
        var success = TextSharpHelper.ExportTableToPdf(title, table, pdfFile, isLandscape, includeHeader, headerAlignment, headerFontSize, rowFontSize, headerFixHeight);
        //提示信息
        var message = success ? "导出操作成功" : "导出操作失败";
        if (success)
        {
            Growl.SuccessGlobal(message);
            Process.Start("explorer.exe", pdfFile);
        }
        else
        {
            Growl.ErrorGlobal(message);
        }
    }
}

通过把List<T>的列表转换为常规的DataTable来处理,我们就可以利用之前我们随笔《在Winform分页控件中集成导出PDF文档的功能》介绍到的PDF导出函数来实现WPF数据导出到PDF的处理。

上面的 TextSharpHelper 就是对于itext7进行的封装,实现PDF的导出处理。

引入相关的Nugget类后,封装它的辅助类代码如下所示。

/// <summary>
    /// 基于iText7对PDF的导出处理
    /// </summary>
    public static class TextSharpHelper
    {
        /// <summary>
        /// datatable转PDF方法
        /// </summary>
        /// <param name="title">标题内容</param>
        /// <param name="data">dataTable数据</param>
        /// <param name="pdfFile">PDF文件保存的路径</param>
        /// <param name="isLandscape">是否为横向打印,默认为true</param>
        /// <param name="includeHeader">是否每页包含表头信息</param>
        /// <param name="headerAlignment">头部的对其方式,默认为居中对其</param>
        /// <param name="headerFontSize">头部字体大小</param>
        /// <param name="rowFontSize">行记录字体大小</param>
        /// <param name="headerFixHeight">头部的固定高度,否则为自适应</param>
        /// <returns></returns>
        public static bool ExportTableToPdf(string title, DataTable data, string pdfFile, bool isLandscape = true, bool includeHeader = true, iText.Layout.Properties.HorizontalAlignment headerAlignment = iText.Layout.Properties.HorizontalAlignment.CENTER, float headerFontSize = 9f, float rowFontSize = 9f, float? headerFixHeight = null)
        {var writer = new PdfWriter(pdfFile);
            PdfDocument pdf = new PdfDocument(writer);
            pdf.SetDefaultPageSize(isLandscape ? PageSize.A4.Rotate() : PageSize.A4); //A4横向
            var doc = new Document(pdf);//设置标题
            if (!string.IsNullOrEmpty(title))
            {
                var param = new Paragraph(title)
                         .SetFontColor(iText.Kernel.Colors.ColorConstants.BLACK)
                         .SetBold()  //粗体
                         .SetFontSize(headerFontSize + 5)
                         .SetTextAlignment(TextAlignment.CENTER); //居中
                doc.Add(param);
            }
            var table = new Table(data.Columns.Count)
                .SetTextAlignment(TextAlignment.CENTER)
                .SetVerticalAlignment(VerticalAlignment.MIDDLE)
                .SetWidth(new UnitValue(UnitValue.PERCENT, 100));//缩放比例
            table.UseAllAvailableWidth();
            //添加表头
            foreach (DataColumn dc in data.Columns)
            {
                var caption = !string.IsNullOrEmpty(dc.Caption) ? dc.Caption : dc.ColumnName;
                var cell = new Cell().Add(new Paragraph(caption))
                    .SetBold()
                    .SetVerticalAlignment(VerticalAlignment.MIDDLE)
                    .SetHorizontalAlignment(headerAlignment)
                    .SetPadding(1)
                    .SetFontSize(headerFontSize);
                if (headerFixHeight.HasValue)
                {
                    cell.SetHeight(new UnitValue(UnitValue.POINT, headerFixHeight.Value));
                }
                table.AddHeaderCell(cell);
            }
            //插入数据
            var colorWhite = Color.ConvertRgbToCmyk(iText.Kernel.Colors.WebColors.GetRGBColor("White"));// System.Drawing.Color.White;
            var colorEvent = iText.Kernel.Colors.WebColors.GetRGBColor("LightCyan");// System.Drawing.Color.LightCyan;
            var EventRowBackColor = Color.ConvertRgbToCmyk(colorEvent);
            for (int i = 0; i < data.Rows.Count; i++)
            {
                table.StartNewRow();//第一列开启新行
                var backgroudColor = ((i % 2 == 0) ? colorWhite : EventRowBackColor);
                for (int j = 0; j < data.Columns.Count; j++)
                {
                    var text = data.Rows[i][j].ToString();
                    var cell = new Cell()
                        .SetBackgroundColor(backgroudColor)
                        .SetFontSize(rowFontSize)
                        .SetVerticalAlignment(VerticalAlignment.MIDDLE)
                        .Add(new Paragraph(text));
                    table.AddCell(cell);
                }
            }
            doc.Add(table);
            pdf.Close();
            writer.Close();
            return true;
        }
    }

导出PDF的文档效果如下所示。

 

4、导入Excel数据

Excel数据的导入,可以降低批量处理数据的难度和繁琐的界面一个个录入,这种是一种常见的操作方式,我们主要提供固定的模板给客户下载录入数据,然后提交进行批量的导入即可。

导入的界面处理,我们这里涉及一个通用的导入界面(和WInform端的界面类似),这样我们每个不同的业务导入处理都可以重用,只需要设置一些不同的属性,以及一些事件的处理即可,如下是通用的界面效果。

我们这里主要针对性的介绍它的设计方式,前面我们介绍,在业务界面里面调用它的时候,如下代码所示。

/// <summary>
/// 导出内容到Excel
/// </summary>
[RelayCommand]
private void ImportExcel()
{
    var page = App.GetService<ImportExcelData>();
    page!.ViewModel.Items?.Clear();
    page!.ViewModel.TemplateFile = $"系统用户信息-模板.xls";
    page!.OnDataSave -= ExcelData_OnDataSave;
    page!.OnDataSave += ExcelData_OnDataSave;
    //导航到指定页面
    ViewModel.Navigate(typeof(ImportExcelData));
}

这个通用的窗体里面的视图模型,定义了一个模板的文件名称,以及一个通用的数据DataTable的集合,以及一个事件用于子类的导入转换的实现,它的视图模型类代码如下所示。

/// <summary>
    /// 批量导入Excel数据的视图模型基类
    /// </summary>
    public partial class ImportExcelDataViewModel : BaseViewModel
    {
        [ObservableProperty]
        private string templateFile;
        [ObservableProperty]
        private string importFilePath;
        [ObservableProperty]
        private DataTable items;

我们为了给客户打开模板文件,方便用于录入Excel数据,因此我们在本地打开模板文件即可。

/// <summary>
        /// 打开模板文件
        /// </summary>
        [RelayCommand]
        private void OpenFile()
        {
            if (!this.TemplateFile.IsNullOrEmpty())
            {
                var realFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.TemplateFile);
                if (File.Exists(realFilePath))
                {
                    Process.Start("explorer.exe", realFilePath);
                }
                else
                {
                    MessageDxUtil.ShowError($"没有找到该模板文件:{realFilePath}");
                }
            }
        }

在通用的导入页面的后台代码里面,我们需要实现一些如选择Excel后,显示数据到DataGrid的操作,以及批量保存数据的处理。

/// <summary>
        /// 选择Excel文件后,显示Excel里面的表格数据
        /// </summary>
        [RelayCommand]
        private void BrowseExcel()
        {
            string file = FileDialogHelper.OpenExcel();
            if (!string.IsNullOrEmpty(file))
            {
                this.ViewModel.ImportFilePath = file;
                ViewData();
            }
        }
/// <summary>
        /// 查看Excel文件并显示在界面上操作
        /// </summary>
        private void ViewData()
        {
            if (this.txtFilePath.Text == "")
            {
                MessageDxUtil.ShowTips("请选择指定的Excel文件");
                return;
            }
            try
            {
                var myDs = new DataSet();
                string error = "";
                AsposeExcelTools.ExcelFileToDataSet(this.txtFilePath.Text, out myDs, out error);
                this.ViewModel.Items = myDs.Tables[0];
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                MessageDxUtil.ShowError(ex.Message);
            }
        }

导入处理的操作代码如下所示。

/// <summary>
/// 批量保存数据到数据库
/// </summary>
/// <returns></returns>
[RelayCommand]
private async Task<CommonResult> SaveData()
{            
    if (ViewModel.Items == null || ViewModel.Items?.Rows?.Count == 0)
        return new CommonResult(false);
    if (MessageDxUtil.ShowYesNoAndWarning("该操作将把数据导入到系统数据库中,您确定是否继续?") ==  System.Windows.MessageBoxResult.Yes)
    {
        var dt = this.ViewModel.Items;
        foreach (DataRow dr in dt.Rows)
        {
            try
            {
                await OnDataSave(dr);
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                MessageDxUtil.ShowError(ex.Message);
            }
        }
        return new CommonResult(true, "操作成功");
    }
    return new CommonResult(false);
}

注意,我们这里使用了事件的处理,把数据的转换逻辑留给子类去实现的。

/// <summary>
        /// 数据保存的事件
        /// </summary>
        public event SaveDataHandler OnDataSave;

这样我们在用户信息的导入页面UserListPage.xaml.cs里面的代码就可以根据实际的情况进行实现事件了。

/// <summary>
    /// 导出内容到Excel
    /// </summary>
    [RelayCommand]
    private void ImportExcel()
    {
        var page = App.GetService<ImportExcelData>();
        page!.ViewModel.Items?.Clear();
        page!.ViewModel.TemplateFile = $"系统用户信息-模板.xls";
        page!.OnDataSave -= ExcelData_OnDataSave;
        page!.OnDataSave += ExcelData_OnDataSave;
        //导航到指定页面
        ViewModel.Navigate(typeof(ImportExcelData));
    }

这个事件的实现,主要就是把个性化的用户信息(用户信息模板里面定义的字段),转换为DataTable的行信息即可,如下代码所示。具体根据模板设计的情况进行修改即可。

具体就不再一一赘述,主要就是基类逻辑和具体实现分离,实现不同的业务功能处理即可。

以上即是我们一个列表通用页面里面,往往需要用到的通用性的导入、导出操作的介绍,希望对读者在开发WPF应用功能上有所启发,有所参考,善莫大焉。

 

链接附注

如对我们的代码生成工具有兴趣,可以到官网下载使用《代码生成工具Database2Sharp》。

如需了解我们官网对《SqlSugar开发框架》的介绍,可以参考《SqlSugar开发框架》了解。

如需阅读我们对于《SqlSugar开发框架》文章介绍,可以参考博客园的随笔标签《SqlSugar随笔 , WPF随笔》学习了解。

 

专注于代码生成工具、.Net/.NetCore 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架等框架产品。
 转载请注明出处:撰写人:伍华聪  http://www.iqidi.com

相关文章
|
3月前
|
C# 开发者 Windows
WPF 应用程序开发:一分钟入门
本文介绍 Windows Presentation Foundation (WPF),这是一种用于构建高质量、可缩放的 Windows 桌面应用程序的框架,支持 XAML 语言,方便 UI 设计与逻辑分离。文章涵盖 WPF 基础概念、代码示例,并深入探讨常见问题及解决方案,包括数据绑定、控件样式与模板、布局管理等方面,帮助开发者高效掌握 WPF 开发技巧。
173 65
|
4月前
|
C# UED 开发者
WPF与性能优化:掌握这些核心技巧,让你的应用从卡顿到丝滑,彻底告别延迟,实现响应速度质的飞跃——从布局到动画全面剖析与实例演示
【8月更文挑战第31天】本文通过对比优化前后的方法,详细探讨了提升WPF应用响应速度的策略。文章首先分析了常见的性能瓶颈,如复杂的XAML布局、耗时的事件处理、不当的数据绑定及繁重的动画效果。接着,通过具体示例展示了如何简化XAML结构、使用后台线程处理事件、调整数据绑定设置以及利用DirectX优化动画,从而有效提升应用性能。通过这些优化措施,WPF应用将更加流畅,用户体验也将得到显著改善。
305 1
|
4月前
|
容器 C# Docker
WPF与容器技术的碰撞:手把手教你Docker化WPF应用,实现跨环境一致性的开发与部署
【8月更文挑战第31天】容器技术简化了软件开发、测试和部署流程,尤其对Windows Presentation Foundation(WPF)应用程序而言,利用Docker能显著提升其可移植性和可维护性。本文通过具体示例代码,详细介绍了如何将WPF应用Docker化的过程,包括创建Dockerfile及构建和运行Docker镜像的步骤。借助容器技术,WPF应用能在任何支持Docker的环境下一致运行,极大地提升了开发效率和部署灵活性。
151 1
|
4月前
|
安全 C# 数据安全/隐私保护
WPF安全加固全攻略:从数据绑定到网络通信,多维度防范让你的应用固若金汤,抵御各类攻击
【8月更文挑战第31天】安全性是WPF应用程序开发中不可或缺的一部分。本文从技术角度探讨了WPF应用面临的多种安全威胁及防护措施。通过严格验证绑定数据、限制资源加载来源、实施基于角色的权限管理和使用加密技术保障网络通信安全,可有效提升应用安全性,增强用户信任。例如,使用HTML编码防止XSS攻击、检查资源签名确保其可信度、定义安全策略限制文件访问权限,以及采用HTTPS和加密算法保护数据传输。这些措施有助于全面保障WPF应用的安全性。
62 0
|
4月前
|
C# 开发者 Windows
全面指南:WPF无障碍设计从入门到精通——让每一个用户都能无障碍地享受你的应用,从自动化属性到焦点导航的最佳实践
【8月更文挑战第31天】为了确保Windows Presentation Foundation (WPF) 应用程序对所有用户都具备无障碍性,开发者需关注无障碍设计原则。这不仅是法律要求,更是社会责任,旨在让技术更人性化,惠及包括视障、听障及行动受限等用户群体。
95 0
|
4月前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
109 0
|
4月前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
118 0
|
4月前
|
存储 C# 关系型数据库
“云端融合:WPF应用无缝对接Azure与AWS——从Blob存储到RDS数据库,全面解析跨平台云服务集成的最佳实践”
【8月更文挑战第31天】本文探讨了如何将Windows Presentation Foundation(WPF)应用与Microsoft Azure和Amazon Web Services(AWS)两大主流云平台无缝集成。通过具体示例代码展示了如何利用Azure Blob Storage存储非结构化数据、Azure Cosmos DB进行分布式数据库操作;同时介绍了如何借助Amazon S3实现大规模数据存储及通过Amazon RDS简化数据库管理。这不仅提升了WPF应用的可扩展性和可用性,还降低了基础设施成本。
95 0
|
7月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
398 0
|
4月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件