1、DSkin入门教程和注意事项新人必看-2018-3-30 DSkin入门教程和注意事项 1. 通过授权客户端更新和下载dll,包含了以下4个文件 DSkin.dll是主要的控件库 DSkin.Design.dll是开发和设计的支持库,如果没有引用,里面大部分控件将不能在设计器里正常使用,而且会报未授权,发布的时候不需要该dll。 DSkin.xml是VS的智能提示文件,对DSkin.dll里面的方法属性等提供提示说明 更新文档.txt 是DSkin的更新日志,可以查看DSkin更新的功能和控件以及修复的BUG 为.net版本,根据项目需求下载相应的版本,.net版
2、本尽可能一致,这样不容易出问题。 2.0版本的是包含Linq的,使用的时候可以加上using System.Linq; 2. 使用的时候需要引用DSkin.dll和DSkin.Design.dll,另外DSkin.xml需要和DSkin.dll放在同一个目录,一般是Debug目录。把DSkin里面的控件添加工具箱,可以新建个名称为DSkin的选项卡,直接把DSkin.dll拖到工具箱里面就可以了。 3. 窗体的使用: 添加窗体,继承DSkinForm 注意:DSkinForm Layered模式下支持DSkin的大部分控件,以及其他一部分带有Paint事
3、件的控件, 对于不支持的控件需要使用ControlHost控件来承载, 把那些控件放在ControlHost里面。 ControlHost不能相互嵌套,只能一层。 因为ControlHost是一个独立的窗体,添加之后会在控件最顶层, 尽可能的少用或者不用ControlHost, 如果你不需要透明效果和动画效果,你可以直接把窗体的IsLayeredWindowForm改成False,关闭Layered模式,这样窗体就可以支持其他普通控件了,可以不需要ControlHost Layered模式是指DSkinForm的IsLayeredWindowForm为true Lay
4、ered模式的优势:更高的呈现效率,更好的渲染效果,不会闪烁,支持窗体的任意透明,支持窗体动画。 QQ、迅雷、酷狗等等都是采用这种方式呈现的 缺点:不能很好的支持普通控件 做异形窗体,在Layered模式下,把背景色设置成透明色,然后设置透明的PNG图片为背景就可以了 如果要将窗体当成子窗体添加到其他窗体或者控件里面需要将该子窗体的IsLayeredWindowForm改成False,否则会报创建句柄错误。 DSkin里的DSkinDataGridView、DSkinSplitPanel、DSkinChatRichTextBox、DCSkinComboBox不支
5、持Layered模式 4. 常用控件的主要事项: DSkinButton、DuiButton: 适应图片大小,这个时候控件尺寸由NormalImage的图片尺寸决定, 是否为纯色,默认会绘制一层样式层。 可以设置按钮风格 DSkinListBox、DuiListBox: 添加完项目之后要调用LayoutContent();方法,现在一般可以不需要手动调用了 项目布局的位置偏移,可以通过设置项目的Margin属性来控制 启用多行多列的时候,项目布局由ItemSize属性决定,如果是浮动布局可以不需要设置ItemSize 浮动布局 DSkinLis
6、tBox绑定数据源和设置模板 //设置模板 dSkinListBox1.Template = typeof(DSkinListItemTemplate); dSkinListBox1.DataSource = data; //设置数据源 模板设计为虚拟控件设计,继承DSkinListItemTemplate //通过重写OnLoad方法或者注册Load事件来设置绑定值 protected override void OnLoad(EventArgs e) { base.OnLoad(e); d
7、uiPictureBox1.Image = (Image)this.Eval("字段名1"); duiLabel1.Text = this.Eval("字段名2").ToString(); } DSkinListBox、DuiListBox 的选择模式,可以设置为无,单选和多选 启用选择之后设置选择效果,绑定ListBox的ItemSelectedChanged事件,通过这个事件来设置项目的效果 DSkinCombobox、DuiCombobox 将每行文字转换成一个项目 选中的项目显示方式,False是文本显示方式,True
8、的时候是控件图像显示方式 添加的Item是虚拟控件 DSkinTreeView 添加节点 for (int i = 0; i < 100; i++) { DSkinTreeViewNode dNode = new DSkinTreeViewNode(); dNode.Text = "根节点" + i.ToString(); dNode.IsCustom = true;//启用自定义样式 dNode.ShowCheckBox = f
9、alse; dSkinTreeView1.Nodes.Add(dNode); for (int j = 0; j < 10; j++) { DSkinTreeViewNode nodenode = new DSkinTreeViewNode(); nodenode.Text = "子节点" + j.ToString(); dNode.Nodes.Add(nodenode);
10、 for (int k = 0; k < 10; k++) { DSkinTreeViewNode nodenodenode = new DSkinTreeViewNode(); nodenodenode.Text = "子子节点" + k.ToString(); nodenodenode.Template = typeof(DSkinTreeViewNodeTemplate);//自定义模板
11、 nodenode.Nodes.Add(nodenodenode); } } } //dSkinTreeView1.LayoutContent();//现在一般可以不需要手动调用了 Brush控件和Pen控件 大部分控件都有类似这个属性 这些就是设置笔刷的属性,使用的时候从工具箱里选择一个笔刷添加到设计器设置好笔刷的属性,然后绑定到对应控件的笔刷属性上 DSkinGridList 注意:不要用设计器添加列,有个BUG还未解决,建议写代码添加列 st
12、ring[] cs = new string[] { "列1", "列2" }; foreach (string item in cs) { dSkinGridList1.Columns.Add(new DSkinGridListColumn { Name = item, Width = 50 }); } 或者用linq的写法 dSkinGridList1.Columns.AddRange(cs.Select(a => new DSkinGridListColumn { Name = a, Width = 50 }).ToArray()); 绑
13、定数据源 //设置模板,模板是继承DSkin.Controls.DSkinGirdListCellTemplate dSkinGridList1.Columns[2].CellTemplate = typeof(Component2); object[] data = new object[10000]; Image bt = Properties.Resources.bt; for (int i = 0; i < data.Length; i++) { data[i] = new { 状态 = "23状态", 图片
14、 bt, 姓名 = "24dfs" + i, ID = i }; } dSkinGridList1.DataSource = data;//绑定数据源,数据源可以是DataTable,DataSet,List等等,没有设置模板的列需要设置DataPropertyName 属性来关联绑定的字段名 更新数据源的时候,如果数据源对象没有变,直接调用DataBind()就可以更新数据显示了 手动添加数据 需要 using DSkin.Controls; for (int i = 0; i < 500; i++) {
15、 dSkinGridList1.Rows.AddRow(i, "asda" + i, "hgsf", "kjt"); } 自定义分页数据 private void dSkinGridList1_PageIndexChanged(object sender, EventArgs e) { //CustomPage 自定义分页为true,RowCount可以自定义,设置总数据量。在PageIndexChanged事件可以通过添加Row或者重新绑定数据源来加载对应页面的数据
16、 //1、添加Row数据 dSkinGridList1.Rows.Clear(); for (int i = 0; i < 100; i++) { dSkinGridList1.Rows.AddRow(dSkinGridList1.PageIndex, "测试数据", 231, i); } //2、绑定对应页面的数据 Image bt = Properties.Resources.bt
17、 List
18、 需要设置TabControl属性来关联窗体上的DSkinTabControl才能使用,DSkinTabItem为虚拟控件,可以继承来设计效果 关联的TabControl,可以设置ItemSize为1,1来隐藏头部 DSkinHtmlLabel、 DSkinHtmlToolTip 这两个控件可以支持简单的Html和CSS,添加的图片可以支持http:// 和file:///的url,也自定义image的关键词通过ImageLoad事件来处理加载的图片 Image image = Image.FromFile("Images//1_100.gif");
19、 private void duiHtmlLabel1_ImageLoad(object sender, DSkin.Html.Core.Entities.HtmlImageLoadEventArgs e) { e.Callback(image); e.Handled = true; } //查询元素 var a = dSkinHtmlLabel1.HtmlContainer.Root.Query(c => c.TagName == "img").ElementAt(0)
20、 a.MouseUp += (s, E) =>//绑定事件 { Console.WriteLine("MouseUp" + E.Location); }; DuiBrowser、 DSkinBrowser 使用浏览器控件需要在群里下载Wke.dll,plugins目录的NPSWF32.dll是Flash插件,如果不使用Flash可以删除 duiBrowser1.InvokeJS("alert('aaa')");//调用JS触发 AlertBox事件 //JS 调用C#,建议把委托定义成全局的,防止被回
21、收 jsNativeFunction js = new jsNativeFunction(a => { MessageBox.Show(new JsValue(a, 0).ToString());//获取JS调用C#的参数,后面的数字是参数索引 return JsValue.JsString(a, "测试");//JS调用C#方法之后的返回值 }); duiBrowser1.JsBindFun("msgBox", js, 1);//绑定C#的方法,msgBox是方法名,数字为绑定到JS里的方法参数数量
22、 网页里只要用JS调用 msgBox('aa123测试'); //这样就可以回调调用C#的方法了 新版的是采用Ewe内核的,群里下载Ewe的dll,比之前的wke更加完善一些。使用方式差不多。不过提供更加便捷的JS调用C#的方法 先设置调用方法的对象 定义js要调用的C#的方法,DSkin.DirectUI.JSFunction 特性加到要调用的方法上;参数和返回值要对应; 最后网页中的JS直接调用Test('哈哈123test',1000) 就可以回调给对应的C#方法了 C#调用JS,JS调用C#,获取返回值,弹出窗体显示结果 JS的Alert弹窗
23、那些需要通过AlertBox这些事件来捕获,自己定义弹窗。否则没有弹窗显示 读取程序内嵌网页,和WebUI实现方式一样,看下面的 采用Html开发桌面程序 就是添加程序集,网页设置为内嵌资源,设置URL 注意:XP系统上无法使用flash插件 浏览器控件不建议加到用户控件里。如果要加,请写代码添加,判断DesignMode。设计模式下不要创建浏览器控件。否则会报无法加载dll的问题 DSkinChart 定义X轴显示的文字 定义图表样式 绑定数据源,数据源可以是集合、数组、DataTable、DataSet List
24、
25、ata = new ArrayList[2]; ChartData[0] = new ArrayList(); Random r = new Random(); for (int i = 0; i < 7; i++) { ChartData[0].Add(r.Next()); } ChartData[1] = new ArrayList(); for (int i = 0; i
26、 < 7; i++) { ChartData[1].Add(r.Next()); } dSkinChart1.DataSource = ChartData; DSKinGroupBox 注意:添加的控件设置属性可能会无效,需要手动将生成的代码调整顺序。 这个BUG暂时无法解决 将DSKinGroupBox的代码移到其他控件下面,然后再随便改一下设计器的控件,让设计器重新整理生成的代码这样添加到DSKinGroupBox的控件设置的属性就有效果了。 5. 虚拟控件的
27、使用: 可以通过实体控件的智能任务卡添加,或者DUIControls属性里添加 虚拟控件支持单个组件复制和粘贴,选中需要复制的虚拟控件,Ctrl+C,然后点击选中目标控件,Ctrl+V就可以把虚拟控件复制到目标控件了。需要注意暂时还不能同时复制控件内部的虚拟控件,复制过去的虚拟控件位置不变,另外需要支持虚拟控件设计模式的控件才可以作为目标控件粘贴。否则粘贴之后虚拟控件的Parent属性为Null,需要手动设置Parent属性,才可以转移到目标控件。 如果通过设计器虚拟控件集合添加的虚拟控件没有添加到界面上,你可以在属性栏里的组件下拉框里找,如果有的话,设置该虚拟控件的Pare
28、nt属性到你需要添加到的控件里,如果不能设置,你重新打开设计器就可以了 DSkinBaseControl上的虚拟控件才可以在设计器上拖拽 虚拟控件支持多选,用Ctrl键多选,可以用来同时设置多个控件的属性 可以通过这几个属性来控制虚拟控件在设计模式下的行为 虚拟控件支持文档设计模式,右键添加组件,把继承类改成DuiBaseControl或者其他虚拟控件就可以了。 这样虚拟控件就像用户控件一样,可以直接设计,可以往里面添加虚拟控件和组件。做列表项目什么的都很方便。 虚拟控件集合支持Linq查询和Lambda表达式查询 Query扩展方法需要添加us
29、ing DSkin.DirectUI;
//查询dSkinBaseControl1里面的所有DuiLabel 并执行动画
dSkinBaseControl1.InnerDuiControl.Query
30、 Rectangle rect = Screen.PrimaryScreen.WorkingArea; int top = (rect.Height - Height) / 2; this.Location = new Point(rect.Width - Width, top); int centerLeft = (rect.Width - Width) / 2; this.DoEffect(() => { if (Left > centerLeft + 4)
31、 { Opacity = 1 - 1.0 * (Left - centerLeft) / (rect.Width - Width - centerLeft); Left -= ((Left - centerLeft) / 5); return true;//继续动画执行 } Opacity = 1; return false;//停止动画执行 }); 7. 虚拟控件的SendTask 方法的使用 在使
32、用自定义模板的时候经常会遇到需要处理模板的虚拟控件的事件,如果采用外部遍历虚拟控件来绑定事件,会感觉很麻烦,所以加增加了这个SendTask方法。 使用的时候很简单,只要需要在模板里绑定对应的处理事件,里面调用SendTask方法,把任务发送出去,然后通过对应的承载的实体控件或者父级虚拟控件的AcceptTask 的事件来处理就行了。 比如:这个是一个DSkinGridList的Cell模板,我需要的就是DuiCheckBox被选中的时候,弹出一个消息框,然后我就在这个模板里绑定这个虚拟控件的CheckedChanged事件 通过这个事件来发送任务。然后,我们需要接收这个任务, 可
33、以在窗体的Load事件里绑定承载这个Cell模板的实体控件的AcceptTask 事件,通过这个事件来接受刚才定义在Cell模板里的任务,接收到了之后,执行该任务。 8. 采用Html开发桌面程序 《新版WebUI开发模式点这里》 用DSkin的Html开发桌面的优势: 1. 支持DPI缩放,不会出现界面模糊和界面过小的问题 2. 有海量的界面模板资源,可以支持JQuery,Bootstrap等等插件 3. 只要一点点Html基础的就行了,开发界面很简单,易上手 4. 支持JS和C#相互调用 5. 附加的dll小,才3M,比起用Cef那个小太多了 缺点:不能完全兼
34、容Html5和CSS3,毕竟dll体积那么小,不能包含所有浏览器的功能,显示速度比不上浏览器。内存占用,比普通的桌面程序稍微耗内存。 开发准备: 项目右键添加窗体,改继承,改成DSkin.Forms.WebUIForm 项目右键,添加放Html文件的目录,比如View 群里下载 WebUI的模板文件,放到这个View目录里,右键修改这个模板文件的属性 生成操作,改成嵌入的资源,所有相关的Html,图片还是CSS,JS文件都要改这个属性 打开那个index.html,在ui-content 这个DIV里面加入你要的内容,然后保存 在之前添加的窗体的构
35、造函数里设置资源的链接,file:/// 要3个斜杠 最后,设置刚才的窗体为主窗体,然后添加资源,生成就可以运行了 注意事项:网页里的资源链接都要用相对路径,当然也可以是http开头的网络资源,比如 DPI的支持,需要项目设置配置 把这里的配置取消注释,默认是注释掉的 如果没有这个文件,打开项目属性 点击启用,取消启用,然后就会在Properties生成那个文件 关于窗体尺寸大小,假如你希望正常的情况下窗体打开时候尺寸为100*100,但是100*100在高DPI屏幕下,设置屏幕缩放了的情况下,会显的很小。所以你需要根据DPI缩放调整窗体尺寸,你希
36、望的尺寸乘以ZoomFactor 窗体的缩放比例属性,假如屏幕缩放是125%的,然后就变成125*125了,这样就不会显的小了。 JS和C#调用,看上面的DSkinBrowser说明,这里可以不需要设置GlobalObject。 默认集成了这几个事件,可以在网页中自动触发的 默认集成的Js可以直接调用的方法 Console_WriteLine("输出");//调试的时候,这个方法可以控制台输出 ResizeWindow("righttop");//调整窗体大小 MoveWindow();//移动窗体 Command_Min();//最小化窗体 Co
37、mmand_MaxOrNor();//最大化或者还原窗体 Command_Close();//关闭窗体 GetWindowState();//获取窗体最大化,最小化状态 如果需要其他事件和方法,需要自己封装。 调试JS可以通过ConsoleMessage 事件来获取错误消息 窗体上面不要放控件,里面的内容全部用Html来定义 对于使用框架页面 frame标签的可以设置命名空间映射Html和C# 代码,一个页面对应一个C#类。页面逻辑就可以写在对应的C#类里 这个要注释掉 不能有多个相同名称的框架页面文件,比如不同目录里都有index.
38、html而且都用框架来加载 封装好了一个异步获取数据的方法,简化JS里异步获取数据的操作 新的异步调用方法: C#方法定义和之前同步方法一样 只要Js调用这个方法的时候,最后一个参数用有一个参数的回调函数就可以了。执行这个C#方法之后,这个方法的返回值会通过这个回调函数设置。 异步调用 这里的回调参数a就是上面C#方法的返回值 同步调用 注意:异步调用C#方法,如果C#方法里有操作UI的,需要委托到主线程 新版WebUI开发模式 新版开发模式采用MiniBlink内核,这个内核更新,功能更完善,而且提供开发者功能,内核
39、还在更新中,而且是开源项目: 如果是内核方面的问题可以到 提问 mb.dll群里下载 开始开发 新建X86的Winform项目,窗体继承改成DSkin.Forms.MiniBlinkForm 窗体尺寸设置和旧版的一样,期望大小乘以ZoomFactor,是为了适应DPI缩放; 这段DPI代码取消注释,如果没有app.manifest,可以在项目属性里,点击启用,再取消启用就有这个文件了 程序集里的资源Url写法是res://开头的 不是之前的file:/// res://WebUIDemo/Views/index.html
40、res://程序集名/若干文件夹/文件名 区分大小写 文件属性要改成嵌入的资源 Html页面和C#类绑定,C#类代码就写在之前设置的 页面和类的名称要一样,Html在哪个文件夹无所谓,区分大小写, 支持主页面和框架页面的绑定。旧版的不支持主页面绑定 类继承 DSkin.Forms.MiniBlinkPage C#属性和页面双向绑定,依赖Vue,支持简单属性的双向绑定,和集合的单向绑定,复杂属性请用Json字符串 JS中也可以用Get(“属性名”); Set(“属性名”,值) 访问和设置属性值,可以不需要Vue 属性写法
41、 string text = "文字"; public string Text { get { return text; } set { OnPropertyChanged(value, ref text); } } Html页面必须引用 vue.js Vue2.0 页面设置一个绑定的全局ID,默认是page,如果想改成其他的,页面和C#类需要一起改,在构造函数里设置 页面里的 {{Text}} 就是绑定到C#里定义的Text的属性了
42、绑定操作写好之后,Js中就可以操作这个Vue绑定对象了,对象名就是那个Id,默认为page Js中的高级操作可以到Vue官网查看教程 https://cn.vuejs.org/v2/guide/ 比如Js中设置 page.Text=’这么牛逼!’; 这个值就会更新到C#类Text属性 集合绑定: using DSkin.Forms; 集合必须用MiniBlinkCollection 才能绑定,泛型,可以支持简单的类对象绑定 构造函数里添加集合数据 假如你在其他地方修改了集合属性,必须调用集合的S
43、aveChanges();方法才能更新到UI 页面中的绑定写法,如果不懂的话,可以到Vue官网看看集合绑定写法 v-for="item in 属性名" Js绑定C#方法和旧版一样,方法前面加JSFunction,方法参数只支持简单的数据类型,数量和类型要和JS调用的对应 JS同步调用C#方法:参数对应,直接调用就是同步调用 JS异步调用C#方法:前面参数对应,最后加个包含一个参数的回调函数 如果页面里引用了JQuery,你还可以用C#封装的JQuery调用,方便操作Dom元素 C#调用JS: InvokeJS
44、"alert('test')"); 开发者工具 程序目录里需要放这个资源包,群里下载,比如Debug目录。发布不需要带这个资源包 点一下窗体,按Ctrl +Alt +Q 打开开发者工具 这个放大镜元素选择暂时不能用,可以用页面右键检查代替 开发者工具暂时不支持断点调试,断点会导致整个程序卡主。 控制台是可以用的 这些浏览器内核功能以MiniBlink更新为准 Flash支持 目录里放flash插件就可以了 Html5视频的话,将来会更新支持,也是插件方式 9. 关于群里的案例源码,旧版的源码引用新版的dll会报错,是因为dll升级了,把原来的一部分属性或者方法删除了或者修改了,所以只要把报错的那些代码删除了,基本上就可以了。还有什么问题,可以在群里提问!






