分类:
C#日记ASP.net(vs2008平台下)(31)
版权声明:本文为博主原创文章,未经博主允许不得转载。
有时候闲的无聊,看到extjs那么肥大,真想把自己的项目改了,最近看到一款轻型的UI感觉不错,但是在网上找了好多教程,但是没有一个是完全是C#asp.net写的
无耐下,自己写了下,感觉效果不错,故拿出来和大学分享一下,希望可以抛砖引玉作用.
由于好多人都只是拷贝代码,故在此全用图片作说明.
图片效果图1
这个界面是上左右下结构
左边是一棵树
右边是一个表格
上部是标题
最下部只是一个空的保留一部分空间
下面开始说下整体结构HTML代码如下
至于HTML代码不想在做多余的解说
下面开始左边的树,在easyUI里面是有树的,但这里没有用,在这里还得感谢Ferry's blogs提供的dTree树,在网上叫无级树,因为它扩展性还是比较好的,在此就用它吧.
在用它之前还是先看下dtree 说明文档,在下载这树JS里面有详细的说明
在上面<head>里面树这样写,不懂可以看下文档这里就不作多解释了.
[javascript] view plain
copy
-
- d = new dTree('d');
- d.add(0, -1, '个人面板');
- function getData(id) {
- $.ajax({
- url: 'TreeSource/GetTreeData.ashx?parentID=' + id,
- type: 'post',
- datatype: 'json',
- success: function (JsonValureturne) {
-
- if (JsonValureturne) {
-
-
- var json = eval("(" + JsonValureturne + ")");
-
-
-
- $.each(json.Menu, function (key, value) {
- if (id == 0) {
-
- d.add(value.ID, value.ParentMenuID, value.MenuName, '', value.MenuName, '', 'img/folder.gif', 'img/folderopen.gif');
-
- }
- else {
- d.add(value.ID, value.ParentMenuID, value.MenuName, "javascript:addTab('" + value.MenuName + "','" + value.MenuClickURL + "')", value.MenuName, '');
-
- }
-
- getData(value.ID);
-
- })
- }
- else {
- $("#divTree").html(d.toString());
-
-
- }
- }
- })
- }
- $(getData(0));
-
-
这里我们引用一个后台文件'TreeSource/GetTreeData.ashx?parentID=' + id
意思就是传给后台一个父ID,返回一组json数据
数据库结构这里也贴出来吧,以防有人不理解.
像这样 设计如果还是不懂,请参考dtree文档
下面重点来讲解后台如何来处理及返回数据据的.
- <%@ WebHandler Language="C#" Class="GetTreeData" %>
- using System;
- using System.Web;
- using System.Data;
- using System.Collections;
- using System.Collections.Generic;
- using System.Web.Script.Serialization;
- public class GetTreeData : IHttpHandler
- {
- public bool IsReusable
- {
- get { return false; }
- }
- public void ProcessRequest(HttpContext context)
- {
-
-
-
-
-
-
- context.Response.ContentType = "text/plain";
- if (!String.IsNullOrEmpty(GetParentID(context)))
- {
- string ParentID = GetParentID(context);
- DataTable dt = SqlHelper.FillDataTable(String.Format(
- "SELECT * FROM SunZonTMSMenu WHERE ParentMenuID={0}", ParentID
- ));
- IList<Menu> menu = new List<Menu>();
- if (dt != null && dt.Rows.Count > 0)
- {
- foreach (DataRow dr in dt.Rows)
- {
- menu.Add(new Menu()
- {
- ID = Int32.Parse(dr["ID"].ToString()),
- ParentMenuID = Int32.Parse(dr["ParentMenuID"].ToString()),
- MenuName = dr["MenuName"].ToString(),
- MenuCode = dr["MenuCode"].ToString(),
- MenuClickURL = dr["MenuClickURL"].ToString()
- });
- }
- }
- if (menu.Count > 0)
- {
- context.Response.Write(FormatToJson.ListToJson<Menu>(menu));
- }
- }
- }
- public string GetParentID(HttpContext context)
- {
- return context.Request["parentID"];
- }
- }
这里使用一个类库SqlHelper.FillDataTable()及IList<Menu> menu = new List<Menu>() meun类
还有一个FormatToJson.ListToJson<T>(T))泛型方法,别吓着了,其它很简单.
先分析一下这里的总体思路.
1)获取前台的父ID
2)通过此ID在数据里查找相应的数据
3)再把返回的数据据填充到自定义的类里面,可能问为什么这样做,因为这样做可以利用反射的方法很好的外理数据,下面会详细的说明
4)把形成的类集合IList<Menu>格式化成json数据并返回给前台
看下怎么查找数据SqlHelper.FillDataTable()方法
就这么简单
下面再看下类Meun
注意了这个类是在VS2010上面写的,每个成员类型必须和数据库一致,
下面关健的一部就是把这个类集合格式化JSON数据,来看下代码
好了,这些基本上完成了转化的方法,
我们来看看前台返回的娄据是什么样的,相信很多人都明白了
如果出现这些数据说明就成功了
这里做下说明吧,Meun就是我们的类名称,数据库里面是什么型的数据这里必须返回什么样的类型,很多json示例都是引号的,这里看到了吧,并不是json数据都用引号,希望这点大家要理解,这也是标准的Json数据形式,为什么我们要把ID作为整形呢,因为我们传给后台的时候用整形或者数据库设计一般都用整形这样可以设主健等等好处,
前台接收数据的时候需要注意的var json = eval("(" + JsonValureturne + ")");
因为我们返回的时候是以字符串形式返回的,必须用eval转化下或者paserjson方法都行的,eval用了双的括号(),这样是把里面的数据才真正意思上的转化为对象
详细请看eval用法,这里就不多说了.
这样一棵树就做好了.
下面开始说右边的内容区
右边是采用jQuery easyUI tab面板详情请参考tab文档
在head头部境加代码
[javascript] view plain
copy
-
- $(function () {
- $('#tt').tabs({
- tools: [{
-
- iconCls: 'icon-add',
- handler: function () {
- alert('add');
- }
- }, {
- iconCls: 'icon-save',
- handler: function () {
- alert('save');
- }
- }]
- });
- });
-
- function addTab(tit, link) {
- if ($('#tt').tabs('exists', tit)) {
- $.messager.alert('提示消息', '窗口已经打开。', 'info');
-
- } else {
- $('#tt').tabs('add', {
- title: tit,
-
- content: '<iframe scrolling="yes" frameborder="0" src="' + link + '" style="width:100%;height:98%;"></iframe>',
- fit: true,
- closable: true
- });
- }
- }
-
这样我们的面板就好了.
下面再看面板里的表是怎么增加的
[javascript] view plain
copy
- $('#roleList').datagrid({
- title: '',
- loadMsg: "数据加载中,请稍后……",
- nowrap: false,
- striped: true,
- collapsible: true,
- url: 'ashx/RoleHandler.ashx',
- pageList: [10, 15, 20, 25, 30, 40, 50],
- pageSize: 15,
- sortName: 'RoleSort',
- sortOrder: 'asc',
- remoteSort: false,
- idField: 'RoleCode',
- frozenColumns: [[
- { field: 'ck', checkbox: true },
- { title: '角色编码', field: 'RoleCode', width: 120, align: 'center', sortable: true }
- ]],
- columns: [[
- { field: 'RoleName', title: '角色名称', width: 120, align: 'center', sortable: true },
- { field: 'RoleSort', title: '默认排序', width: 80, align: 'center', sortable: true },
- { field: 'opt', title: '操作', width: 100, align: 'center',
- formatter: function (value, rec) {
- return '<a href="#" onclick="parent.addTab(\'编辑角色[' + rec.RoleName + ']\', \'Role/Edit.aspx?RoleCode=' + rec.RoleCode + '&RoleName=' + rec.RoleName + '\')"><span style="color:red">编辑</span></a>';
- }
- }
- ]],
- pagination: true,
- rownumbers: true,
- onLoadSuccess: function () {
- $('.datagrid-toolbar').append($('#txtSearch'));
- $('#txtSearch').show();
- },
- toolbar: [
- {
- id: 'btnadd',
- text: '添加',
- iconCls: 'icon-add',
- handler: function () {
- parent.addTab('添加角色', 'Role/Edit.aspx');
- }
- }, {
- id: 'btncut',
- text: '删除',
- iconCls: 'icon-cut',
- handler: function () {
- var codes = getSelections();
- if (codes == '') {
- $.messager.alert('提示消息', '请选择要删除的数据!', 'info');
- } else {
- $.messager.confirm('提示消息', '确定要删除所选数据吗?', function (r) {
- if (r) {
- $('#processWindow').window('open', 'aadasdsads');
- $.ajax({
- url: 'ashx/RoleHandler.ashx?Codes=' + codes,
- type: 'post',
- datatype: 'text',
- success: function (returnValue) {
- if (returnValue) {
- $('#processWindow').window('close');
- $('#roleList').datagrid('reload');
- $('#roleList').datagrid('clearSelections');
- }
- }
- });
- }
- });
- }
- }
- }, '-',
- {
- id: 'btnSearch',
- text: '搜索',
- disabled: false,
- iconCls: 'icon-search',
- handler: function () {
- $('#roleList').datagrid('options').url = 'ashx/RoleHandler.ashx?RoleName=' + escape($('#txtSearch').val());
- $('#roleList').datagrid("reload");
- }
- }
- ]
- }).datagrid("columnMoving");
- });
-
- function getSelections() {
- var ids = [];
- var rows = $('#roleList').datagrid('getSelections');
- for (var i = 0; i < rows.length; i++) {
- ids.push(rows[i].RoleCode);
- }
- return ids.join(',');
- }
- <table id="roleList">
- </table>
- <div id="processWindow" class="easyui-window" closed="true" modal="true" title="提示消息"
- style="width: 300px; height: 60px;">
- <div id="windowContent" class="general-font">
- <img src="jqueryPager/jquery-easyui/themes/gray/images/panel_loading.gif" />
- 操作进行中,请稍后...
- </div>
- </div>
- <input type="text" id="txtSearch" title="请输入角色名称" style="display: none;" />
下面是后台处理的代码
- <%@ WebHandler Language="C#" Class="RoleHandler" %>
-
- using System;
- using System.Web;
- using System.Data;
- using System.Collections;
- using System.Collections.Generic;
- using System.Web.Script.Serialization;
- public class RoleHandler : IHttpHandler
- {
- #region IHttpHandler Members
-
- public bool IsReusable
- {
- get { return true; }
- }
-
- public void ProcessRequest(HttpContext context)
- {
- context.Response.ContentType = "text/plain";
- SqlHelper sqlhelper=new SqlHelper();
- if (!String.IsNullOrEmpty(GetRoleCodes(context)))
- {
- String codes = GetRoleCodes(context);
- codes = "'" + codes.Replace(",", "','") + "'";
- SqlHelper.ExecuteNonQuery(string.Format("delete from Roles where RoleCode in({0})", codes));
- context.Response.Write("true");
- }
- else
- {
- int Count;
- int pagesiz=GetPageSize(context);
- int page=GetPageIndex(context);
- DataTable dt = new DataTable();
- string sqlWhere = string.Format("RoleName like '%{0}%'", GetRoleName(context));
- DataSet ds= SqlHelper.m_QueryPagination("Roles","*",sqlWhere,"RoleSort",pagesiz,page,out Count);
- dt = ds.Tables[0];
- IList<Roles> list = new List<Roles>();
- if (dt != null && dt.Rows.Count > 0)
- {
- foreach (DataRow dr in dt.Rows)
- {
- list.Add(new Roles()
- {
- RoleCode = dr["RoleCode"].ToString(),
- RoleName = dr["RoleName"].ToString(),
- RoleSort = int.Parse(dr["RoleSort"].ToString())
- });
- }
- }
-
- if (list.Count > 0)
- {
- dt.Clear();
- string data = FormatToJson.ListToJson<Roles>(list, "rows");
- data = data.Substring(1);
- context.Response.Write(
- "{ \"total\":" +Count + "," +data);
- }
- }
- }
-
- public String GetRoleCodes(HttpContext context)
- {
- return context.Request["Codes"];
- }
-
- public Int32 GetPageSize(HttpContext context)
- {
- try
- {
- return Int32.Parse(context.Request["rows"].ToString());
- }
- catch
- {
- return 10;
- }
- }
-
- public Int32 GetPageIndex(HttpContext context)
- {
- try
- {
- return Int32.Parse(context.Request["page"].ToString());
- }
- catch
- {
- return 1;
- }
- }
-
- public String GetRoleName(HttpContext context)
- {
- return context.Request["RoleName"];
- }
-
- #endregion
- }
- #region jquery easyUI专用带返回总数分页存储过程
- /**
-
- USE [Roles]
- GO
-
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- ALTER procedure [dbo].[AspNetPage]
- @tblName varchar(1000),
- @SelectFieldName varchar(4000),
- @strWhere varchar(4000),
- @OrderFieldName varchar(255),
- @PageSize int ,
- @PageIndex int = 1,
- @iRowCount int output,
- @OrderType bit = 0
-
- AS
- declare @strSQL varchar(4000)
- declare @strTmp varchar(4000)
- declare @strOrder varchar(400)
- declare @strRowCount nvarchar(4000)
-
- set @OrderFieldName=ltrim(rtrim(@OrderFieldName))
-
- if @OrderType != 0
- begin
- set @strTmp = '<(select min'
- set @strOrder = ' order by ' + @OrderFieldName +' desc'
- end
-
- else
- begin
- set @strTmp = '>(select max'
- set @strOrder = ' order by ' + @OrderFieldName +' asc'
- end
-
- set @strSQL = 'select top ' + str(@PageSize) + @SelectFieldName+' from ' + @tblName + ' where ' + @OrderFieldName + @strTmp + '('
- + right(@OrderFieldName,len(@OrderFieldName)-charindex('.',@OrderFieldName)) + ') from (select top ' + str((@PageIndex-1)*@PageSize)
- + @OrderFieldName + ' from ' + @tblName + @strOrder + ') as tblTmp)' + @strOrder
-
- if @strWhere != ''
- set @strSQL = 'select top ' + str(@PageSize) + @SelectFieldName+' from ' + @tblName + ' where ' + @OrderFieldName + @strTmp + '('
- + right(@OrderFieldName,len(@OrderFieldName)-charindex('.',@OrderFieldName)) + ') from (select top ' + str((@PageIndex-1)*@PageSize)
- + @OrderFieldName + ' from ' + @tblName + ' where ' + @strWhere + ' ' + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
-
- if @PageIndex = 1
- begin
- set @strTmp = ''
- if @strWhere != ''
- set @strTmp = ' where ' + @strWhere
- set @strSQL = 'select top ' + str(@PageSize) + @SelectFieldName+' from ' + @tblName + @strTmp + ' ' + @strOrder
- end
-
- exec(@strSQL)
-
- if @strWhere!=''
- begin
- set @strRowCount = 'select @iRowCount=count(*) from ' + @tblName+' where '+@strWhere
- end
- else
- begin
- set @strRowCount = 'select @iRowCount=count(*) from ' + @tblName
- end
-
- exec sp_executesql @strRowCount,N'@iRowCount int out',@iRowCount out
-
-
- **/
-
- #endregion
这样基本上就完成了,看下再这几个效果,说不定会有意外的收获.
这个图说明easyUi gridview本身就有鼠标经过每行里自动改变背景色的功能,
这个图有点类似extjs的分页功能,说明它具有分页大小可以根据下列表形式选择,很不错的功能.
这个图片说明列宽拖动也是自带的,哈哈,真不错哦再看下面
这个图充分说明了我们前面固定前面的两例保持不变
后面的项可以滚动,这项有时候很实用.其实还有很多不错的功能,比如说列宽自适应,数据可以格式化,列可以编缉,可以增加下列选择项列等等,这里不详细介绍了
下面我们看看网上很多站点使用的很炫列支持拖动,
easyui gridview本身是不支持列拖动的,但是UI里面却有可支持拖动的方法,详情请参见文档
网上有文章这样写的,
[javascript] view plain
copy
- <script type="text/javascript">
- var cols = [{ field: 'testName', title: '<span class="dropitem">测试名</span>', align: 'center',width:120 },
- { field: 'testValue', title: '<span class="dropitem">测试值</span>', align: 'center', width: 120}];
- var url="/Test/Test1Data";
- $(document).ready(function () {
- init();
- drag();
- });
- function init() {
- $("#test").datagrid({
- url: url,
- type: "post",
- datatype: "json",
- width: 600,
- height: 280,
- loadMsg: "数据加载中,请稍后...",
- nowrap: true,
- rownumbers: false,
- pagination: true,
- singleSelect: true,
- columns: [cols],
-
- onLoadSuccess: function (data) {
- drag();
- }
- });
- }
-
- function drag() {
- $('.datagrid-header-inner .datagrid-cell').draggable({
- revert: true,
- proxy: 'clone'
- }).droppable({
- accept: '.datagrid-header-inner .datagrid-cell',
- onDrop: function (e, source) {
-
- var src = $(e.currentTarget.innerHTML).html();
-
- var sou = $(source.innerHTML).html();
- var tempcolsrc;
- var tempcolsou;
- var tempcols=[];
- for (var i = 0; i < cols.length; i++) {
- if (cols[i].title == sou) {
- tempcolsrc = cols[i];
- }
- else if (cols[i].title == src) {
- tempcolsou = cols[i];
- }
- }
- for (var i = 0; i < cols.length; i++) {
-
- var col = {
- field: cols[i].field,
- title: cols[i].title,
- align: cols[i].align,
- width: cols[i].width
- };
- if (cols[i].title == sou) {
- col = tempcolsou;
- }
- else if (cols[i].title == src) {
- col = tempcolsrc;
- }
- tempcols.push(col);
- }
- cols = tempcols;
-
-
- timeid = setTimeout("init()", 1000);
- }
- });
- }
- </script>
-
- <div id="test"></div>
感觉这个人写的很不错,思路很清淅,但是这个方法我没有采用,因为不宜扩展,这里还得谢谢上面提供的思路.
下面看扩展方法
[javascript] view plain
copy
- $(function () {
-
- $.extend($.fn.datagrid.methods, {
- columnMoving: function (jq) {
- return jq.each(function () {
- var target = this;
- var cells = $(this).datagrid('getPanel').find('div.datagrid-header td[field]');
- cells.draggable({
- revert: true,
- cursor: 'pointer',
- edge: 5,
- proxy: function (source) {
- var height = $(source).height();
- var width = $(source).width() - 20;
- var bordercolor = $(source).css("background-color");
- var p = $('<div class="tree-node-proxy tree-dnd-no" style="position:absolute;border:1px solid ' + bordercolor + '"/>').appendTo('body');
- p.css({ "background-color": bordercolor });
- p.html($(source).text());
- p.height(height);
- p.width(width);
- p.hide();
- return p;
- },
- onBeforeDrag: function (e) {
- e.data.startLeft = $(this).offset().left;
- e.data.startTop = $(this).offset().top;
- },
- onStartDrag: function () {
- $(this).draggable('proxy').css({
- left: -10000,
- top: -10000
- });
- },
- onDrag: function (e) {
- $(this).draggable('proxy').show().css({
- left: e.pageX - 30,
- top: e.pageY - 5
- });
- return false;
- }
- }).droppable({
- accept: 'td[field]',
- onDragOver: function (e, source) {
- $(source).draggable('proxy').removeClass('tree-dnd-no').addClass('tree-dnd-yes');
- $(this).css('border-left', '1px solid #ff0000');
- var left = $(this).offset().left -5;
- var top1 = $(this).offset().top - 10;
- var top2 = $(this).offset().top +24;
- var pgb1 = $('<div id="guang1" style="position:absolute; index-z:888888;background:#fff url(img/guangbiao1.gif) no-repeat 0 0;width:10px;height:8px"></div>').appendTo('body');
- var pgb2 = $('<div id="guang2" style="position:absolute; index-z:888888;background:#fff url(img/guangbiao2.gif) no-repeat 0 0;width:12px;height:12px"></div>').appendTo('body');
- pgb1.css({ "top": top1, "left": left });
- pgb2.css({ "top": top2, "left": left });
-
- },
- onDragLeave: function (e, source) {
- $(source).draggable('proxy').removeClass('tree-dnd-yes').addClass('tree-dnd-no');
- $(this).css('border-left', 0);
- $("body #guang1").hide();
- $("body #guang2").hide();
- },
- onDrop: function (e, source) {
- $(this).css('border-left', 0);
- $("body #guang1").hide();
- $("body #guang2").hide();
- var fromField = $(source).attr('field');
- var toField = $(this).attr('field');
- setTimeout(function () {
- moveField(fromField, toField);
- $(target).datagrid();
- $(target).datagrid('columnMoving');
- }, 0);
- }
- });
-
-
- function moveField(from, to) {
- var columns = $(target).datagrid('options').columns;
- var cc = columns[0];
- var c = _remove(from);
- if (c) {
- _insert(to, c);
- }
-
- function _remove(field) {
- for (var i = 0; i < cc.length; i++) {
- if (cc[i].field == field) {
- var c = cc[i];
- cc.splice(i, 1);
- return c;
- }
- }
- return null;
- }
- function _insert(field, c) {
- var newcc = [];
- for (var i = 0; i < cc.length; i++) {
- if (cc[i].field == field) {
- newcc.push(c);
- }
- newcc.push(cc[i]);
- }
- columns[0] = newcc;
- }
- }
- });
- }
- });
调用的时候只要在后面加上$('#roleList').datagrid({...}).datagrid("columnMoving");这句就行了,怎么样,简单吧,还有听过几位网友的说,把拖动的时候上下指示箭头做成闪动的效果更好些,这些细节这里不作多解释,好了就写到这吧,祝使用asp.net C#语言的人能够参考,
创建复杂列表头请参见...
转载请注明原出处!http://blog.csdn.net/guyongqing52/article/details/7833211