看过之前设计器截图的朋友应该有印象,可能会发觉我们的设计器UI设计布局其实类似Visual studio 的设计界面,采用的是左、中、右三个区域布局。左侧为控件区域、中间为表单的画布设区域、右侧为属性区域。这样的UI设计肯定就得支持控件的拖拽设计,用户只要拖放一个控件到我们的画布上,那么画布就应该立即能够看到我们拖放的控件在画布中的位置、大小、以及一些控件自带的默认信息。不用说这样的设计对于用户来说不论在操作体验上还是设计的感官上都更加直接和方便,因为我在设计阶段就可以知道我设计后的表单在系统运行时候的样子(What i see is what i get)。这个设计相对于我们1.0版本的设计器来说应该是很大的进步,要知道在1.0时代我们的设计器可是一个通过弹出框,然后在弹出框的下拉控件列表去选择控件类型,然后配置其他的xx属性......然后所有控件显示到一个grid列表中的,用户更不不知道这个表单是什么样子,还需要借助预览功能才能查看表单的样子。
我们的设计器既然要采用类似VS设计器的方式,那么我们也就必须解决一些比较重要的问题。
- 首先来说就是必须要支持控件的拖拽设计,也就是当用户进入我们的设计器界面,选择了左侧的某个控件后能够拖放到我们设计器的中间画布“指定”区域(注意是指定的位置,不是顺便一个位置)。
- 然后就是不同区域支持的控件类型可能不一样,那么我们就必须限定每个类型的区域控件能够支持哪些控件。也就是当一个被区域支持的控件拖放到我们的区域上面并释放鼠标后那么我们的区域就得接受该控件,如果是不被支持的控件拖放到我们的区域上面并释放鼠标后我们的区域控件不会有任何响应。
- 同一个区域内部的控件支持随意的交换位置,用户可在一个区域内部通过拖放控件来改变控件的位置。
- 我们的区域之间能够支持控件的拖放,比如将一个A区域的控件移动到B区域中区。也就是区域之间可以随意交换控件。
上面的几个问题是我们采用拖拽式表单设计器必须解决的问题,如何解决呢?通过研究extjs API 我们可以发现,对于extjs treepanel类型控件我们在它的view里面添加一个支持树节点拖放的treeviewdragdrop插件,实现代码如下:(请对比Ext.net 的写法和 纯extjs的写法上的区别.其实它们本质上是一样的,Ext.Net的代码在经过服务器解析之后生成的代码其实和纯extjs写的代码几乎一样。只是Ext.Net对.Net开发人员来说使用起来更方便,更熟悉,仅此而已.)
1 <ext:TreePanel ID="controlRegion" Title="表单控件" runat="server" Region="West" RootVisible="false" 2 Width="200" Split="true" Collapsible="true" Collapsed="false"> 3 <Store> 4 ...........................略 5 </Store> 6 <Root> 7 ...........................略 8 </Root> 9 <View> 10 <ext:TreeView ID="TreeView1" runat="server"> 11 <Plugins> 12 <ext:TreeViewDragDrop runat="server" EnableDrop="true" DragGroup="tree2div" /> 13 </Plugins> 14 </ext:TreeView> 15 </View> 16 </ext:TreePanel>
Ext.create("Ext.tree.Panel",
{
store: { //.........略 },
id: "TreePanel1",
width: 200,
region: "west",
split: true,
collapsible: true,
title: "表单控件",
viewConfig: {
id: "TreeView2",
plugins: [
{
ptype: "treeviewdragdrop",
dragGroup: "tree2div"
}
],
xtype: "treeview"
},
root: { //.........略 },
rootVisible: false
})
请注意代码中的包含treeviewdragdrop部分的代码,它的加入表示我们的树节点可以支持拖放了,但是仅仅这样还是远远不够的。我们还必须为我们设计器的画布提供接收拖放功能的代码,这里我们给出画布区域的代码和对画布支持拖放的代码。
我们的设计器代码中加入一个画布的panel ,结合前面一章节的介绍大家应该知道我们的画布其实是一个Mixed类型的混合区域控件。
1 <ext:Panel ID="mainPanel" runat="server" Region="Center" ButtonAlign="Center" Border="true" 2 BodyPadding="10" OverflowY="Auto"> 3 <CustomConfig> 4 <ext:ConfigItem Name="type" Value="Mixed" Mode="Value" /> 5 </CustomConfig> 6 </ext:Panel>
然后我们使用一个Droptarget来为我们的画布添加可以接收拖动释放的控件的功能
<ext:DropTarget ID="ddt" runat="server" Target="mainPanel" Group="tree2div" IgnoreSelf="false"> <NotifyDrop Fn="notifyDrop" /> <NotifyEnter Handler="ftConfig.isDraging=true;" /> </ext:DropTarget>
在这里注意一个地方就是在droptarget里面的group属性值为tree2div,这个值和我们前面给treepanel添加的treeviewdragdrop 的DragGroup属性值是必须一致的,不然是不能正常工作的。到目前为止我们其实仅仅解决了树的节点可以拖放,以及我们的mainpanel画布支持接受拖放过来的控件。但是我们的画布如何处理拖放过来的控件,以及每种区域控件可以接收的控件等等功能还得我们去设计和定义,具体的设计以及实现留到下一节吧。