本文将分享《WEEX跨平台开发实战》出版啦的详细内容,并且还将对跨平台web开发进行详尽解释,此外,我们还将为大家带来关于.NetCore跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存、
本文将分享《WEEX跨平台开发实战》出版啦的详细内容,并且还将对跨平台web开发进行详尽解释,此外,我们还将为大家带来关于.Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存、08.《Electron 跨平台开发实战》- chapter08-深入集成(shell模块)、动态启动菜单项、AgileEAS.NET平台开发实例-药店系统-报表开发(下)、C#开发经验分享:跨平台开发实践的相关知识,希望对你有所帮助。
本文目录一览:- 《WEEX跨平台开发实战》出版啦(跨平台web开发)
- .Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存
- 08.《Electron 跨平台开发实战》- chapter08-深入集成(shell模块)、动态启动菜单项
- AgileEAS.NET平台开发实例-药店系统-报表开发(下)
- C#开发经验分享:跨平台开发实践
《WEEX跨平台开发实战》出版啦(跨平台web开发)
简介
序言
近年来,伴随着大前端概念的提出和兴起,移动端和前端的边界变得越来越模糊,一大批移动跨平台开发框架和模式涌现出来。从早期的PhoneGap、Inoic 等Hybrid技术,到现在耳熟能详的React Native、WEEX和Flutter等跨平台技术,无不体现着移动端开发的前端化。
作为阿里巴巴开源的一套移动跨平台技术框架,WEEX框架最初是为了解决移动开发过程中频繁发版和多端研发的问题而开发的。具体来说,使用WEEX提供的跨平台开发技术,开发者可以很方便地使用Web前端技术来构建高性能、可扩展的原生性能体验,并支持在Android、iOS和Web等多平台上进行部署。
作为目前主流的跨平台技术框架之一,WEEX项目使用Vue.js进行编写,对于熟悉Web前端开发的开发者来说,其是一个不错的选择。在性能和项目迭代方面,WEEX与PhoneGap、Inoic等Hybrid技术相比也有一定的优势。
不过由于种种原因,WEEX的社区生态并不是很完善,也没有一本系统介绍WEEX的书籍。基于对跨平台技术的热爱,以及积累的一些WEEX项目实战经验,笔者思量再三决定对WEEX框架进行系统的梳理,并将其整理成书。
“路漫漫其修远兮,吾将上下而求索。”通过对WEEX技术的学习和本书的写作,笔者深刻地意识到“学无止境”的含义。如果本书对你学习WEEX有所帮助和启发,笔者将不胜欣慰。
如何阅读本书
本书共分为9章,章节概要如下。
第1章~第4章:这4章属于WEEX入门与基础部分。这部分内容主要包括WEEX简介、WEEX环境搭建、WEEX基础知识以及WEEX开发常用的组件和模块等内容。同时,本部分内容配备了大量的实例,通过这部分内容的学习,读者将会对WEEX有一个基本的认识。
第5章~第8章:这4章属于WEEX进阶部分。这部分内容主要由讲述Rax、Vue.js、BindingX和WEEX Eros的章节组成,主要是介绍WEEX开发中的一些进阶知识。同时,为了加快WEEX的开发效率,建议开发者直接使用WEEX Eros和weexplus等WEEX脚手架。
第9章:这一章属于WEEX项目实战部分。这部分讲述了WEEX项目实战的内容,是对WEEX基础知识的综合运用。通过此部分的知识讲解,读者将会对WEEX有一个全面的认识。
希望通过本书的讲解,读者可以对WEEX技术有一个全面的了解,并能够使用它进行移动跨平台项目的开发。
适读人群
本书是一本关于WEEX入门与实战的书籍,适合前端开发者和移动Android/iOS开发者阅读。因此,不管你是一线移动开发工程师,还是有志于从事移动开发的前端开发者,都可以通过学习本书来获取移动跨平台开发的技能。
本书特定
- 基于Vue.js的高性能、轻量级跨平台开发框架;
- 由阿里巴巴开源,并捐赠给Apache基金会进行孵化的项目;
- 全面讲解WEEX框架的各个知识点,并辅以大量案例进行说明,使读者轻松掌握WEEX知识,并应用于实际工作;
- 本书为读者建立了共读群,方便与作者直接进行交流;
- 本书适合所有对移动跨平台开发感兴趣及正在致力于移动跨平台开发工作的读者阅读。
链接
作为国内第一本介绍Weex跨平台开发的书籍,本书详细的介绍了Weex框架开发的方方面面。作为一本实战类型的书籍,本书对原理介绍的比较少,主要还是围绕项目实战,注重基础,在本书构思方面,本书由浅入深,先介绍基础知识,后介绍Weex脚手架(如Weex eros和Weex plus)。最后,通过项目示例来讲解Weex项目开发的内容。
本书可以作为前端开发人员入门客户端开发的书籍,也可以作为客户端开发学习前端知识的跳板。并且,当时我写这本书的目录,更重要的是,想让更多进入阿里的人,能通过学习Weex来了解阿里的技术栈。
废话不多说,下面是本书的链接地址:https://item.jd.com/54156068370.html
参考资料:Weex学习资料
本文同步分享在 博客“xiangzhihong8”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
.Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存
.Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存
1、概述
系统性能优化的第一步就是使用缓存!什么是缓存?缓存是一种效果,就是把数据结果存在某个介质中,下次直接重用。根据二八原则,80%的请求都集中在20%的数据上,缓存就是把20%的数据存起来,直接复用。Web系统缓存主要分为客户端缓存、CDN缓存、反向代理缓存及服务器缓存,而服务器缓存又分类本地缓存、分布式缓存。本节将给大家分享.Net Core 跨平台开发 服务器缓存开发实战。
2、项目创建-ShiQuan.WebTest
-》创建Asp.Net Core3.1 Web项目-shiquan.webtest,添加默认控制器-DefaultController 。
开发环境使用VS2019 aps.net core 3.1
-》Action Index 方法
public IActionResult Index()
{
/*Web 服务器响应请求时,设置缓存Cache-Control。单位为秒。*/
//base.HttpContext.Response.Headers[HeaderNames.CacheControl] = "public,max-age=600";//no-cache
base.ViewBag.Now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
base.ViewBag.Url = $"{base.Request.Scheme}://{base.Request.Host}";//浏览器地址
base.ViewBag.InternalUrl = $"{base.Request.Scheme}://:{this._iConfiguration["port"]}";//应用程序地址
return View();
}
-》在Startup 文件的Configure,使用UseStaticFile 指定当前路径。
//使用UseStaticFile 指定当前路径
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot"))
});
-》复制wwwroot 目录及文件到debug\bin 目录。
-》在Program文件中配置命令行获取参数。
public static void Main(string[] args)
{
//配置命令行获取参数
new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddCommandLine(args)//支持命令行参数
.Build();
CreateHostBuilder(args).Build().Run();
}
-》使用控制台,启动Web项目-dotnet shiquan.webtest.dll --urls=http://*:5177 --port=5177。
-》运行效果
3、本地缓存-MemoryCache
下面我们来进行本地缓存-MemoryCache的开发,首先安装MemoryCache安装包
-》Startup 配置添加MemoryCache的使用。
-》本地缓存的调用
var key = "defaultcontroller_info";
# region 服务器本地缓存-MemoryCache
{
var time = string.Empty;
if(this._iMemoryCache.TryGetValue(key,out time) == false)
{
time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
this._iMemoryCache.Set(key, time);
}
base.ViewBag.MemoryCacheNew = time;
}
#endregion
-》Info 页面内容
@{
ViewData["Title"] = "Home Page";
}
<div>
<h1>Index</h1>
<h2>浏览器地址:@base.ViewBag.Url</h2>
<h2>服务器地址:@base.ViewBag.InternalUrl</h2>
<h2>后台Action时间:@base.ViewBag.Now</h2>
<h2>MemoryCache时间:@base.ViewBag.MemoryCacheNew</h2>
<h2>RedisCache时间:@base.ViewBag.RedisCacheNow</h2>
<h2>CustomCache时间:@base.ViewBag.CustomCacheNow</h2>
<h2>前端View时间:@DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")</h2>
</div>
-》运行效果,后台Action及前端View时间,每次刷新都会更新,而内存缓存首次加载后,都将保存原有时间。
4、分布式缓存-DistributedCache
我们使用Redis作为分布式缓存数据库,首先下载安装配置Redis数据库,Redis数据库默认端口:6379。
-》在.Net core 项目中添加Microsoft.Extensions.Caching.Redis 安装包
-》在Startup文件中配置分布式缓存
/*增加分布式缓存Redis*/
services.AddDistributedRedisCache(option => {
option.Configuration = "127.0.0.1:6379";
option.InstanceName = "DistributedRedisCache";
});
-》控制器调用自定义缓存,实现内容保存与读取,在页面中显示。
#region 分布式缓存-解决缓存在不同实例共享问题
{
var time = this._iRedisCache.GetString(key);
if (string.IsNullOrEmpty(time))
{
time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
this._iRedisCache.SetString(key, time, new DistributedCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(120) //过期时间
});
}
base.ViewBag.RedisCacheNow = time;
}
#endregion
-》运行效果,Redis 缓存在多个客户端中也将不会改变。
5、自定义缓存-CustomCache
我们来进行一次重复造轮子,实现类似内存缓存-MemoryCache的效果。首先我们定义自定义接口-ICustomCache,然后实现自定义缓存CustomCache。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ShiQuan.WebTest.Helpers
{
/// <summary>
/// 自定义缓存接口
/// </summary>
public interface ICustomCache
{
void Add(string key, object value);
T Get<T>(string key);
bool Exists(string key);
void Remove(string key);
}
/// <summary>
/// 自定义缓存
/// </summary>
public class CustomCache:ICustomCache
{
private readonly Dictionary<string, object> keyValues = new Dictionary<string, object>();
/// <summary>
/// 增加内容
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void Add(string key,object value)
{
this.keyValues.Add(key, value);
}
/// <summary>
/// 获取值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T Get<T> (string key)
{
return (T)this.keyValues[key];
}
/// <summary>
/// 判断是否存在
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool Exists(string key)
{
return this.keyValues.ContainsKey(key);
}
/// <summary>
/// 移除值
/// </summary>
/// <param name="key"></param>
public void Remove(string key)
{
this.keyValues.Remove(key);
}
}
}
-》项目注册接口及实现
/*增加自定义缓存*/
//services.AddTransient<ICustomCache, CustomCache>();//进程实例模式
services.AddSingleton<ICustomCache, CustomCache>(); //程序单例模式
-》控制器调用自定义缓存,实现内容保存与读取,在页面中显示。
#region 自定义缓存
{
var time = string.Empty;
if (this._iCustomCache.Exists(key) == false)
{
time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
this._iCustomCache.Add(key, time);
}
time = this._iCustomCache.Get<String>(key);
base.ViewBag.CustomCacheNow = time;
}
#endregion
从运行的效果,我们可以看到,达到类似内存缓存MemoryCache的效果。
至此,.net core 跨平台开发服务器缓存开发实战介绍完毕,有不当地方,欢迎指正!
08.《Electron 跨平台开发实战》- chapter08-深入集成(shell模块)、动态启动菜单项
- 在渲染进程(UI界面)中使用shell模块
- 在应用菜单中使用 shell 模块
- 在上下文菜单中使用 shell 模块
- 禁用菜单项
- !!
- 动态生成菜单
- 禁用菜单:enabled: !!filePath
- 动态启动菜单:createContextMenu().popup();
- 应用菜单
- 应用菜单不同于上下文菜单的特殊点:
- 创建应用菜单(动态处理启用和禁用状态)
- 要点:
- focusedWindow.getRepresentedFilename()只适用于darwin平台
- 程序启动时
- 打开和关闭新窗口时
- 打开新文件时
- 要点:
在渲染进程(UI界面)中使用shell模块
//在文件管理器中打开
const { ..., shell } = require(''electron'');
const showFile = () => {
if (!filePath) { return alert(''This file has not been saved to the file system.''); }
shell.showItemInFolder(filePath);
};
//使用默认程序打开
const openInDefaultApplication = () => {
if (!filePath) { return alert(''This file has not been saved to the file system.''); }
//electron-9.x 已经不存在了
shell.openItem(fullPath)
};
在应用菜单中使用 shell 模块
- applicationMenu.js
{ type: ''separator'' },
{
label: ''Show File'',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
''Cannot Show File\''s Location'',
''There is currently no active document show.''
);
}
focusedWindow.webContents.send(''show-file'');
},
},
{
label: ''Open in Default Application'',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
''Cannot Open File in Default Application'',
''There is currently no active document to open.''
);
}
focusedWindow.webContents.send(''open-in-default'');
},
},
- renderer.js
ipcRenderer.on(''show-file'', showFile);
ipcRenderer.on(''open-in-default'', openInDefaultApplication);
在上下文菜单中使用 shell 模块
- renderer.js
//上下文菜单
const markdownContextMenu = Menu.buildFromTemplate([
...
{
label: ''Show File in Folder'',
click: showFile,
enabled: !!filePath
},
{
label: ''Open in Default'',
click: openInDefaultApplication,
enabled: !!filePath
},
{ type: ''separator'' },
...
]);
markdownView.addEventListener(''contextmenu'', (event) => {
event.preventDefault();
markdownContextMenu.popup();
});
禁用菜单项
!!
!! 常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,在js中新手常常会写这样臃肿的代码:
判断变量a为非空,未定义或者非空串才能执行方法体的内容
var a;
if(a!=null&&typeof(a)!=undefined&&a!=''''){
//a有内容才执行的代码
}
实际上我们只需要写一个判断表达:
if(!!a){
//a有内容才执行的代码...
}
就能和上面达到同样的效果。a是有实际含义的变量才执行方法,否则变量null,undefined和''''空串都不会执行以下代码。
可以总结出来;
“!”是逻辑与运算,并且可以与任何变量进行逻辑与将其转化为布尔值,“!!”则是逻辑与的取反运算,尤其后者在判断类型时代码简洁高效,省去了多次判断null、undefined和空字符串的冗余代码。
动态生成菜单
禁用菜单:enabled: !!filePath
动态启动菜单:createContextMenu().popup();
const createContextMenu = () => {
return Menu.buildFromTemplate([
{ label: ''Open File'', click() { mainProcess.getFileFromUser(); } },
{
label: ''Show File in Folder'',
click: showFile,
enabled: !!filePath
},
{
label: ''Open in Default'',
click: openInDefaultApplication,
enabled: !!filePath
},
{ type: ''separator'' },
{ label: ''Cut'', role: ''cut'' },
{ label: ''Copy'', role: ''copy'' },
{ label: ''Paste'', role: ''paste'' },
{ label: ''Select All'', role: ''selectall'' },
]);
};
markdownView.addEventListener(''contextmenu'', (event) => {
event.preventDefault();
createContextMenu().popup();
});
应用菜单
应用菜单不同于上下文菜单的特殊点:
- 与上下文菜单不同,应用菜单只用一个,所有窗口共享
- 在macOS系统中,甚至应用没有打开窗口的情形。
- 应用菜单存在于主进程中,访问不到渲染进程的变量(这个变量跟菜单项禁用相关)
创建应用菜单(动态处理启用和禁用状态)
要点:
const hasOneOrMoreWindows = !!BrowserWindow.getAllWindows().length; //是否有窗口打开
const focusedWindow = BrowserWindow.getFocusedWindow(); //获取当前焦点窗口,无返回null
const hasFilePath = !!(focusedWindow && focusedWindow.getRepresentedFilename()); //focusedWindow.getRepresentedFilename() 返回窗口打开的文件
focusedWindow.getRepresentedFilename()只适用于darwin平台
- applicationMenu.js
const { app, BrowserWindow, dialog, Menu } = require(''electron'');
const mainProcess = require(''./main'');
const createApplicationMenu = () => {
const hasOneOrMoreWindows = !!BrowserWindow.getAllWindows().length; //是否有窗口打开
const focusedWindow = BrowserWindow.getFocusedWindow(); //获取当前焦点窗口,无返回null
const hasFilePath = !!(focusedWindow && focusedWindow.getRepresentedFilename()); //focusedWindow.getRepresentedFilename() 返回窗口打开的文件
const template = [
{
label: ''File'',
submenu: [
...
{
label: ''Save File'',
accelerator: ''CommandOrControl+S'',
enabled: hasOneOrMoreWindows,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
''Cannot Save or Export'',
''There is currently no active document to save or export.''
);
}
focusedWindow.webContents.send(''save-markdown'');
},
},
{
label: ''Export HTML'',
accelerator: ''Shift+CommandOrControl+S'',
enabled: hasOneOrMoreWindows,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
''Cannot Save or Export'',
''There is currently no active document to save or export.''
);
}
focusedWindow.webContents.send(''save-html'');
},
},
{ type: ''separator'' },
{
label: ''Show File'',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
''Cannot Show File\''s Location'',
''There is currently no active document show.''
);
}
focusedWindow.webContents.send(''show-file'');
},
},
{
label: ''Open in Default Application'',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
''Cannot Open File in Default Application'',
''There is currently no active document to open.''
);
}
focusedWindow.webContents.send(''open-in-default'');
},
},
],
},
...
];
...
return Menu.setApplicationMenu(Menu.buildFromTemplate(template));
};
module.exports = createApplicationMenu;
- main.js
程序启动时
app.on(''ready'', () => {
//Menu.setApplicationMenu(applicationMenu); //设置应用菜单
createApplicationMenu();//设置应用菜单
mainWindow = createwindow();
});
打开和关闭新窗口时
newWindow.on(''focus'', () => {
createApplicationMenu(); //窗口获取焦点时,创建新的应用菜单
});
newWindow.on(''closed'', () => {
...
createApplicationMenu();//关闭一个窗口时,创建新的应用菜单
})
打开新文件时
const openFile = exports.openFile = (targetWindow, file) => {
...
createApplicationMenu(); //打开新文件时,创建新应用菜单
};
AgileEAS.NET平台开发实例-药店系统-报表开发(下)
开篇
我们上篇讲述了如何基于平台的报表管理组件来进行报表的管理,我们并没有说明如何在项目中如何调用,我们设计好的报表。下面我们就来看看,我们如何来使用我们
设计好的报表,一种是直接使用平台原生支持的报表服务,还有一种是我们单独设计实现的报表服务,也就是所谓的脱离现有平台的限制,我们单独使用报表设计器来完成报
表开发工作。并且能够结合其他的平台来进行开发。本章我们就来就这些问题来详细的阐述。
大纲
1、使用原生的报表服务。
2、脱离平台使用报表服务。
使用原生的报表服务
首先、我们先来说明下什么是原生的报表服务,原生的意思是使用平台底层支持的报表管理服务,也可以理解成将报表定义信息保存在平台的底层表“eas.REPORTS”表中
的这样的存储形式。
其次、接着上篇我们讲述的设计报表流程,我们来看下,我们如何使用原生的报表服务,来打印报表。
1、我们在药品入库页面中添加打印事件:
2、在打印事件中添加如下代码。
3、我们来看看打印报表的相关方法:
然后这些代码配置好后,我们来运行下看看效果。
上面也是比较简介,当然还能进行分组,例如我们修改报表按药品类型分组:
大家发现了吧,还是非常的简单的,我们使用起来开发起来也是非常的快捷。并且报表本身提供了导出的功能,支持多种文件格式的导出。下面我们就来看看,我们如何
开发我们不使用AgileEAS.NET平台底部支持的报表,我们单独使用报表的功能如何来做。
脱离平台使用报表
我们现在要脱离AgileEAS.NET的平台来使用报表,我们如何来使用呢?我想我们可以使用如下的几种方式来实现报表功能的调用。下面我们一一道来,但是我们在使用报
表控件的时候,还是会有些不如意的限制,例如:我们新建一个对象报表的时候,我们的对象必须是AgileEAS.NET平台”特定“的对象才可以被报表设计器识别,这里的特定
如何理解呢?下面我们先来看看这个特例吧:
1、找到“bin”或“ref”目录下的报表设计器应用程序:
2、点击“新建”选择对象报表:
3、创建一个新的“对象报表”后,选择数据源:
4、选择报表的数据源实体对象所在的程序集:例如我们现在要开发药品的入库,那么我们可以选择药品入库实体对象所在的程序集:
5、点击“打开”后,报表控件会自动读取该程序集下的所有实体类,前提是该实体类必须是AgileEAS.NET平台规定的实体类,这里怎么里理解呢?我们来看,必须是标
记如下内容:
table特性中的表名可以为空,如果是自定义对象的话。 6、这样报表设计器就能识别出该对象了。
7、我们这里Dm_rin作为我们的设计目标即药品入库:
8、关于报表后续的具体调整,请参考如下报表设计文档:
AgileEAS报表设计器使用说明书.pdf
9、开发完报表后,我们既然不使用AgileEAS.NET平台提供的报表组件支持,那么我们必须自己维护报表的定义文件,不像平台提供的将报表的定义文件保存到数据库
中,那么我们如何来维护报表定义文件呢,我这里给出解决方案如下:在解决方案内新建一个”RDL“文件夹,所有的报表定义文件夹放在该文件夹中。
我们知道报表定义文件的实际存储是以XML格式来存取的就好办了,数据库里面的存储格式也已经清楚了,那么我们就知道了,我们只要从.rdl文件中读取相应的报表定
义信息后就可以了,那这个就应该来说很容易,我们只要写一个辅助类即可,专门负责读取指定路径的指定文件名即可。
我们先来看看为什么说这样直接读取就可以了?
根据报表的名称,读取数据库,来加载该报表的定义信息到报表对象中。
我们来断点一下:
点击文本可视化工具查看具体的内容:
平台提供的读取报表定义的方法:
下面我们就来看看我自己书写的读取rdl文件中的定义信息的辅助类。
1、读取当前工程下的RDL文件夹路径。
2、读取RDL文件夹中的指定名称的报表定义信息:
3、如果存在指定的报表定义文件,读取该定义文件的具体报表定义信息,如果存在多个同名的报表定义文件,则只读取第一个符合条件的文件的信息。
4、这样我们就完成了RDL文件的读取,下面我们来测试下即可知道是否可行:
将上面的通过平台提供的底层组件来访问报表并实现打印的功能,我们通过自定义的报表定义读取Helper类完成报表的打印工作。
5、下面我们来运行下上面的程序:
这样我们就完成了报表的定义和使用,很简单和方便吧,我相信大家能够一学习就能进行二次开发,或者进行报表的开发,当然如果说我们的系统中不存在指定的表映射
对象时,我们这时候需要自定义一个实体对象,此时一定要添加相应的表映射标记与列映射标记,但是此时记得一定不要在表映射标记中写表名。例如:
这样就完成了报表的开发和设计。
总结
上面我们就讲述了基本的关于报表开发的内容,下篇我们讲述报表开发的高级篇,我将将我们内部积累的关于报表设计器的相关经验进行分享,来进行最快速度的报表开
发,跟大家一起分享基于模块的报表开发,能够已最快的速度开发报表。让我们更专注业务的开发,而将一些重复的工作解放出来。
药店系统源码
其他文章
这里附带更多的关于AgileEAS.NET开发平台的说明文章。
1、官方博客:AgileEAS.NET 敏捷软件开发平台
2、作者博客:魏琼东
3、AgileEAS.NET平台-文档发布-还等什么?
4、AgileEAS.NET平台工具之数据原型设计器的使用场景示例
5、更多。。。
更多交流
官方博客:http://www.smarteas.net/
官方网站:http://www.agilelab.cn/
如果您在使用AgileEAS.NET开发平台中有什么问题,请使用如下几种联系方式或者沟通方式。
1、电话-邮箱方式:
何戈洲:hegezhou_hot@163.com 手机:18691480181 博客:http://www.cnblogs.com/hegezhou_hot/
2、QQ交流群:
308961614 网名:H.O.T
原文链接: http://www.cnblogs.com/hegezhou_hot/archive/2011/04/06/2006385.html
C#开发经验分享:跨平台开发实践
C#是一种非常强大的编程语言,可以用于开发各种类型的应用程序。随着移动设备和云计算的发展,跨平台开发变得越来越重要。本文将分享一些C#跨平台开发的实践经验。
一、选择合适的跨平台框架
在进行C#跨平台开发前,我们首先需要选择一个合适的跨平台框架。目前,最常用的跨平台框架之一是Xamarin。Xamarin允许开发者使用C#语言和.NET框架来开发iOS和Android应用。其强大的跨平台能力和丰富的生态系统使得开发者可以同时开发适用于多个平台的应用。
另一个选择是使用.NET Core框架进行跨平台开发。.NET Core是一种开源、跨平台的框架,可以用于开发Windows、Linux和macOS等操作系统的应用。使用.NET Core可以充分发挥C#的优势,同时保持跨平台的兼容性。
根据具体的项目需求和个人经验,选择适合自己的跨平台框架可以提高开发效率和应用性能。
二、充分利用共享代码
在进行C#跨平台开发时,我们可以充分利用共享代码来减少重复开发的工作量。通过共享代码,我们可以在多个平台上复用相同的逻辑和功能,从而使开发过程更加高效。
在使用Xamarin进行跨平台开发时,可以使用共享项目来管理共享代码。共享项目是一种可用于在不同平台上共享代码的特殊项目类型。我们只需要将通用的代码放入共享项目中,然后在各个平台项目中引用即可。这样一来,我们可以重用逻辑和功能,同时保持代码的可维护性和一致性。
在使用.NET Core进行跨平台开发时,可以使用类库项目来管理共享代码。类库项目是一种可以在不同平台上共享的代码库。我们只需要将通用的代码放入类库项目中,然后在不同的平台项目中引用即可。通过类库项目,我们可以实现代码的复用和共享,从而提高开发效率。
三、注意平台差异性
虽然C#具有很强的跨平台能力,但不同平台之间仍然存在差异性。在进行跨平台开发时,我们需要注意这些差异性,并做出相应的处理。
一种常见的差异性是UI控件的不同。不同的平台使用不同的UI控件来展示界面。在进行跨平台开发时,我们需要根据具体的平台来选择和使用相应的UI控件,以保持应用的一致性和用户体验。
另一种常见的差异性是API的不同。不同的平台提供了不同的API,用于访问硬件资源和系统功能。在进行跨平台开发时,我们需要根据具体的平台来调用相应的API,并确保在不同平台上的兼容性。
四、测试和调试
在进行C#跨平台开发时,测试和调试是非常重要的环节。由于不同平台之间存在差异性,我们需要确保应用在不同平台上的稳定性和正常运行。
我们可以通过模拟器或者真机来进行跨平台应用的测试。通过使用模拟器或者真机,我们可以模拟不同平台的环境,从而验证应用在不同平台上的兼容性和可用性。
在进行测试和调试时,我们可以使用调试工具来追踪问题和解决bug。通过使用调试工具,我们可以定位和修复应用中的错误,提高应用的质量和稳定性。
五、持续集成和发布
在进行C#跨平台开发时,持续集成和发布是非常重要的环节。通过使用持续集成和发布工具,我们可以自动化构建和发布应用,从而提高开发效率和软件质量。
可以使用一些流行的持续集成和发布工具,如Jenkins或Azure DevOps。这些工具可以自动构建应用、运行测试、检查代码质量,并将应用发布到目标平台。
除了持续集成和发布工具,我们还可以使用代码仓库和版本控制工具来管理和维护代码。通过使用代码仓库和版本控制工具,我们可以对代码进行版本管理,从而保持代码的可追溯性和可维护性。
总结:
本文分享了一些C#跨平台开发的实践经验。选择合适的跨平台框架、充分利用共享代码、注意平台差异性、测试和调试以及持续集成和发布都是跨平台开发过程中需要关注的重要环节。通过遵循这些实践经验,我们可以更好地进行C#跨平台开发,并提高开发效率和应用质量。
以上就是C#开发经验分享:跨平台开发实践的详细内容,更多请关注php中文网其它相关文章!
关于《WEEX跨平台开发实战》出版啦和跨平台web开发的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于.Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存、08.《Electron 跨平台开发实战》- chapter08-深入集成(shell模块)、动态启动菜单项、AgileEAS.NET平台开发实例-药店系统-报表开发(下)、C#开发经验分享:跨平台开发实践的相关知识,请在本站寻找。
本文标签: