下面我们将讲解在WPF中使用Blazor,并且使用Blazor做一些文件编辑操作,下面是需要用到的东西

  • WPF
  • Blazor
  • Masa Blazor
  • Monaco

安装Masa Blazor模板

使用CMD指令安装模板

dotnet new install MASA.Template

新建Masa Blazor WPF App

  1. 找到如图的模板,然后点击下一步

  2. 下一步,新建项目名称FileEditor

添加Monaco

  1. 打开wwwroot/index.html,并且引用Monaco的依赖,将一下依赖添加到body里面的最尾部。
<script>
var require = { paths: { 'vs': 'https://cdn.masastack.com/npm/monaco-editor/0.34.1/min/vs' } };
</script>
<script src="https://cdn.masastack.com/npm/monaco-editor/0.34.1/min/vs/loader.js"></script>
<script src="https://cdn.masastack.com/npm/monaco-editor/0.34.1/min/vs/editor/editor.main.nls.js"></script>
<script src="https://cdn.masastack.com/npm/monaco-editor/0.34.1/min/vs/editor/editor.main.js"></script>
  1. 新建Pages/Index.razor.cs文件
using System.IO;
using System.Text;
using Masa.Blazor;
using Masa.Blazor.Presets;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop; namespace FileEditor.Pages; public partial class Index : IDisposable
{
/// <summary>
/// 文本内容
/// </summary>
private string value; private MMonacoEditor _editor; private DotNetObjectReference<Index>? _objRef; /// <summary>
/// 定义Monaco的初始配置
/// </summary>
private object options = new
{
language = "md", // 设置语法
automaticLayout = true, // 高度自适应
theme = "vs-dark", // 主题
}; private string fullName; protected override void OnInitialized()
{
_objRef = DotNetObjectReference.Create(this);
} /// <summary>
/// 具体文件路径
/// </summary>
[Parameter]
[CascadingParameter(Name = nameof(FullName))]
public string FullName
{
get => fullName;
set
{
fullName = value;
UpdateValue();
}
} /// <summary>
/// Monaco初始化事件
/// </summary>
private async Task InitMonaco()
{
// 监听CTRL+S 2097 = CTRL+S 快捷键
// 调用Monaco的Command,传递当前对象,并且指定当触发快捷键的时候调用当签对象的指定方法。
await _editor.AddCommandAsync(2097, _objRef, nameof(SaveValue));
} /// <summary>
/// 更新value
/// </summary>
private void UpdateValue()
{
if (string.IsNullOrEmpty(fullName))
{
return;
} var info = new FileInfo(fullName);
if (!info.Exists) return;
using var fileStream = info.OpenText();
value = fileStream.ReadToEnd();
} /// <summary>
/// 更新文件内容
/// </summary>
[JSInvokable]
public async Task SaveValue()
{
try
{
await using var fileStream = File.OpenWrite(fullName);
fileStream.Position = 0;
await fileStream.WriteAsync(Encoding.UTF8.GetBytes(value));
fileStream.Close();
}
catch (Exception e)
{
await PopupService.EnqueueSnackbarAsync(new SnackbarOptions()
{
Title = "保存文件错误",
Content = e.Message
});
}
} public void Dispose()
{
_editor.Dispose();
_objRef?.Dispose();
}
}

Index.razor.cs文件中我们实现了拦截FullName的set,当被set的时候说明上级组件选择了文件并且通过CascadingParameter传递了参数到当前组件。

并且对于当前的Value进行更新,

打开Index.razor

@page "/"
@inject IPopupService PopupService <MMonacoEditor InitCompleteHandle="async () => await InitMonaco()"
@bind-Value="value"
Height="@("100%")"
EditorOptions="options" @ref="_editor">
</MMonacoEditor>

我们对于cs的一些方法和参数进行了绑定,并且bind-value了value的值,我们在cs文件中更新了value就自动更新了UI的显示的值。

然后我们打开Shared/MainLayout.razor文件添加打开文件选择器,从而选择文件。

@using Microsoft.Win32
@inherits LayoutComponentBase <MApp>
<MAppBar App>
<MAppBarNavIcon @onclick="() => _drawer = !_drawer"></MAppBarNavIcon>
<MToolbarTitle>FileEditor</MToolbarTitle>
<MButton OnClick="OpenFile">打开文件</MButton>
<MSpacer></MSpacer>
<MButton Text Color="primary" Target="_blank" Href="https://docs.masastack.com/blazor/introduction/why-masa-blazor">About</MButton>
</MAppBar> <MNavigationDrawer App @bind-Value="_drawer">
<MList Nav Routable>
<MListItem Href="/" ActiveClass="primary--text">
<MListItemIcon>
<MIcon>mdi-home</MIcon>
</MListItemIcon>
<MListItemContent>
<MListItemTitle>Home</MListItemTitle>
</MListItemContent>
</MListItem>
<MListItem Href="/counter" ActiveClass="primary--text">
<MListItemIcon>
<MIcon>mdi-plus</MIcon>
</MListItemIcon>
<MListItemContent>
<MListItemTitle>Counter</MListItemTitle>
</MListItemContent>
</MListItem>
<MListItem Href="/fetchdata" ActiveClass="primary--text">
<MListItemIcon>
<MIcon>mdi-list-box</MIcon>
</MListItemIcon>
<MListItemContent>
<MListItemTitle>Fetch data</MListItemTitle>
</MListItemContent>
</MListItem>
</MList>
</MNavigationDrawer> <MMain>
<MContainer Fluid Style="height: 100%">
<CascadingValue Value="fullName" Name="FullName">
<MErrorHandler>
@Body
</MErrorHandler>
</CascadingValue>
</MContainer>
</MMain>
</MApp> @code { private bool? _drawer; private string fullName; private void OpenFile()
{
var openFileDialog = new OpenFileDialog();
openFileDialog.Title = "请选择您的文件";
openFileDialog.Filter = "文本文件 (*.txt, *.md)|*.txt;*.md";
bool? result = openFileDialog.ShowDialog();
if (result == true)
{
fullName = openFileDialog.FileName;
}
}
}

在这里我们将使用Microsoft.Win32.OpenFileDialog打开文件选择器,并且指定选择文件的类型,

当前文件选择器返回true,则fullName的值,fullName则会通过CascadingValue组件的绑定传递到<CascadingValue></CascadingValue>内的所有子组件。

下面我们看看实际使用效果。

技术交流

qq群:452761192

wx:wk28u9123456789(请备注技术交流)

源码下载地址:https://code-token.oss-cn-beijing.aliyuncs.com/FileEditor.zip

WPF使用Blazor的快速案例的更多相关文章

  1. angularjs 2.0 快速案例(1)

    前言 上一节我们已经把环境给搭建起来了,现在我们通过一个快速案例把angular 2.0 初步了解一下,后续我们会深入每一个细节,这个案例主要是一个[英雄(Hero)]列表的展示,创建,编辑.这个案例 ...

  2. 在WPF的DATAGRID中快速点击出现在ADDNEW或EDITITEM事务过程不允许DEFERREFRESH

    原文 在WPF的DATAGRID中快速点击出现在ADDNEW或EDITITEM事务过程不允许DEFERREFRESH 在项目中关于DataGrid的遇到过一些问题,其中是关于迁入CheckBox的双向 ...

  3. 浅析MyBatis(一):由一个快速案例剖析MyBatis的整体架构与运行流程

    MyBatis 是轻量级的 Java 持久层中间件,完全基于 JDBC 实现持久化的数据访问,支持以 xml 和注解的形式进行配置,能灵活.简单地进行 SQL 映射,也提供了比 JDBC 更丰富的结果 ...

  4. WPF 4.0 DatePicker 快速录入

    WPF 4.0的DatePicker在通过键盘录入日期的时候是非常让人郁闷的.必须按照日期的格式来完整输入例如,比如输入“2010/10/10”才能识别.而实际上在一些要求快速录入的场合,用户更希望直 ...

  5. WPF简单的口算案例

    前几天在博客园,看到有博友利用Winform做了一个口算案例,于是我想把它移植在WPF程序中.Winform程序:http://www.cnblogs.com/ImYZF/p/3345452.html ...

  6. WPF中利用DynamicDataDisplay快速实现示波器功能

    DynamicDataDisplay控件是一个功能很强的绘图工具,除了能生成曲线外,还有很多其他功能,具体见http://dynamicdatadisplay.codeplex.com/.这里你也能下 ...

  7. 【炫丽】从0开始做一个WPF+Blazor对话小程序

    大家好,我是沙漠尽头的狼. .NET是免费,跨平台,开源,用于构建所有应用的开发人员平台. 本文演示如何在WPF中使用Blazor开发漂亮的UI,为客户端开发注入新活力. 注 要使WPF支持Blazo ...

  8. Smart Tag——DevExpress WPF初探

    Smart Tag是一个设计时扩展,所有标准控件均自带这个功能,当然也包括 DevExpress WPF Controls .可以快速设置控件的值或者绑定最重要的属性.它还可以帮助你完成一些重复的工作 ...

  9. ASP.NET Core Blazor Webassembly 之 渐进式应用(PWA)

    Blazor支持渐进式应用开发也就是PWA.使用PWA模式可以使得web应用有原生应用般的体验. 什么是PWA PWA应用是指那些使用指定技术和标准模式来开发的web应用,这将同时赋予它们web应用和 ...

  10. 如何使用MASA.Blazor

    MASA.Blazor 是什么? 基于Material Design设计和BlazorComponent的交互能力提供标准的基础组件库.提供如布局.弹框标准.Loading.全局异常处理等标准场景的预 ...

随机推荐

  1. Netty实战(二)

    一.环境准备 Netty需要的运行环境很简单,只有2个. JDK 1.8+ Apache Maven 3.3.9+ 二.Netty 客户端/服务器概览 如图,展示了一个我们将要编写的 Echo 客户端 ...

  2. 《Linux的文件目录类指令 20条》

    文件目录类的指令 1.pwd指令 查看当前目录 2.ls  指令 查看当前目录所有内容信息 ls -a 显示当前目录所有的文件和目录,包括隐藏的 ls -l 以列表的方式显示信息 ls -al或la ...

  3. 公众号接入 ChatGPT 了!

    虽迟但到,用了一段时间的chatgpt,功能确实令人惊叹,也是第一次体验到了交互式编程.不得不说,未来已来,花了一些时间,终于把chatgpt接入到了公众号! 使用方法 打开公众号的对话框,直接提问! ...

  4. SLAM系统--开启摄像头连接

    博客地址:https://www.cnblogs.com/zylyehuo/ 基于ORB-SLAM3库搭建SLAM系统详见之前的博客 基于ORB-SLAM3库搭建SLAM系统 - zylyehuo - ...

  5. 【LeetCode双向链表】LRU详解,双向链表实战

    LRU缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构. 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity ...

  6. Java(if选择、switch选择、循环)

    1.if 选择结构 //语法 if(表达式){ //语句:(表达式为真) }else{ //语句:(表达式为假) } --------------------------------------- 例 ...

  7. C# 客户端程序 Visual Studio 远程调试方法

    传统桌面客户端的远程调试相比UWP,ASP等项目来说,配置比较麻烦,因为它是非部署的应用程序,原理是复制编译的文件到远程计算机,通过网络来连接和VS的通信,本文主要讲述WPF,WinForm应用程序的 ...

  8. 写博文之必备技能MarkDown

    前言 Markdown是一种轻量级标记语言,排版语法简洁,让人们更多地关注内容本身而非排版.它使用易读易写的纯文本格式编写文档,可与HTML混编,可导出 HTML.PDF 以及本身的 .md 格式的文 ...

  9. 前台vue发送json格式,后台srpeingboot不能自动处理解决办法

    使用HashMap解决,如下图

  10. Profinet转EtherNet/IP网关连接AB PLC的应用案例

    西门子S7-1500 PLC(profinet)与AB PLC以太网通讯(EtherNet/IP).本文主要介绍捷米特JM-EIP-PN的Profinet转EtherNet/IP网关,连接西门子S7- ...