当前位置: 首页 > news >正文

扩展 TreeView 实现选择 CheckBox 自动回发

今天 CSDN 有一网友提出这样的需求: 实现点击 TreeView 的 CheckBox 即自动 PostBack
http://community.csdn.net/Expert/TopicView3.asp?id=5708685

解决方案可以考虑:
1.  在客户端手动通过 js 捕获 checkbox 的 click 事件,然后显示的执行 __doPostBack 方法
     对于如何捕获事件,获取目标节点,与  类似 TreeView几个小技巧  提到的 父子节点CheckBox的级联选择 类似

2. 扩展 TreeNode(继承 System.Web.UI.WebControls.TreeNode)
然而 TreeNode 并未继承自 System.Web.UI.Control,故而无法访问 checkbox 自控件,其无 Render 之类的方法。虽然它对控件开发者提供了 RenderPreText RenderPostText  方法,分别在节点前、后添加自定义信息,但还是无法访问 CheckBox。

看来此路暂时不通icon18.gif

3.  扩展 TreeView,重写 Render,通过 HtmlTextWriter 获取呈现的 html 代码,并想办法遍历其中的 <input type=checkbox /> 为其添加 οnclick=_doPostBack

经测试此法,我看行 14.gif

XTreeView.cs
None.gif using  System;
None.gif
using  System.Data;
None.gif
using  System.Configuration;
None.gif
using  System.IO;
None.gif
using  System.Text;
None.gif
using  System.Text.RegularExpressions;
None.gif
using  System.Web;
None.gif
using  System.Web.Security;
None.gif
using  System.Web.UI;
None.gif
using  System.Web.UI.WebControls;
None.gif
using  System.Web.UI.WebControls.WebParts;
None.gif
using  System.Web.UI.HtmlControls;
None.gif
using  System.Xml;
None.gif
None.gif
namespace  Digdotnet.Test
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// XTreeView 的摘要说明
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class XTreeView : TreeView
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>        
InBlock.gif        
/// 为 checkbox 添加客户端事件 click 处理程序。
InBlock.gif        
/// <remarks>
InBlock.gif        
/// 
InBlock.gif        
/// 默认 TreeView 节点呈现为
InBlock.gif        
/// <input type="checkbox" name="TreeView1n2CheckBox" id="TreeView1n2CheckBox" title="1.1.1" />
InBlock.gif        
/// <a class="TreeView1_0" href="javascript:__doPostBack('TreeView1','s1\\1.1\\1.1.1')" οnclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t2');" id="TreeView1t2">1.1.1</a>
InBlock.gif        
/// 
InBlock.gif        
/// 重写 Render 方法之后呈现为
InBlock.gif        
/// <input type="checkbox" name="TreeView1n2CheckBox" id="TreeView1n2CheckBox" οnclick="TreeView_SelectNode(TreeView1_Data, this.nextSibling,'TreeView1t2');__doPostBack('TreeView1','s1\\1.1\\1.1.1')" title="1.1.1" />
InBlock.gif        
/// <a class="TreeView1_0" href="javascript:__doPostBack('TreeView1','s1\\1.1\\1.1.1')" οnclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t2');" id="TreeView1t2">1.1.1</a>        
InBlock.gif        
/// 
InBlock.gif        
/// </remarks>
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <param name="writer"></param>

InBlock.gif        protected override void Render(HtmlTextWriter writer)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (DesignMode) dot.gif// 设计时,不做处理
InBlock.gif
                base.Render(writer);
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
//            
InBlock.gif
            StringWriter sw = new StringWriter();
InBlock.gif            HtmlTextWriter htmlWriter 
= new HtmlTextWriter(sw);
InBlock.gif            
// 输出 TreeView 的 html 源码
InBlock.gif
            base.Render(htmlWriter);
InBlock.gif            
//
InBlock.gif
            sw.Flush();
InBlock.gif            
string treeHtml = sw.ToString();
InBlock.gif
InBlock.gif            
// 从节点的 <a/> 标记中分析 href 和 onclick 属性中的两个 js 函数,
InBlock.gif            
// 并插入 checkbox 的 onclick 事件
InBlock.gif
            string pattern = @"<input.* (id=.*) title=.*/>[\n\r\s]*<a.* href=.*(__doPostBack.*)"".* οnclick=.*(TreeView_SelectNode.*);"".* id=.*"">";
InBlock.gif            Match match 
= Regex.Match(treeHtml, pattern);
InBlock.gif            
// 正则替换
InBlock.gif
            treeHtml = Regex.Replace(treeHtml, pattern, new MatchEvaluator(ReplaceTextCallback));
InBlock.gif
InBlock.gif            
// 呈现经过处理的 TreeView
InBlock.gif
            writer = new HtmlTextWriter(Context.Response.Output);
InBlock.gif            writer.Write(treeHtml);
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 正则替换回调方法。
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="match"></param>
ExpandedSubBlockEnd.gif        
/// <returns></returns>

InBlock.gif        private static string ReplaceTextCallback(Match match)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
int pos = match.Value.IndexOf(match.Groups[1].Value) + match.Groups[1].Value.Length + 1;
InBlock.gif            
return match.Value.Insert(pos, String.Format(@"οnclick=""{0};{1}"" ", match.Groups[3].Value.Replace("this""this.nextSibling"), match.Groups[2].Value));
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}


测试页面

ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#"  %>
ExpandedBlockStart.gifContractedBlock.gif
<% dot.gif @ Register TagPrefix="ddntest" Namespace="Digdotnet.Test"  %>
None.gif
None.gif
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
None.gif
ExpandedBlockStart.gifContractedBlock.gif
< script  runat ="server" > dot.gif
InBlock.gif
InBlock.gif    protected 
void TreeView1_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{        
InBlock.gif        Label1.Text 
= String.Format("You check the node whose <font color='red'>Text={0} and ValuePath={1}</font>", e.Node.Text, e.Node.ValuePath);        
ExpandedBlockEnd.gif    }

None.gif
</ script >
None.gif
None.gif
< html  xmlns ="http://www.w3.org/1999/xhtml"   >
None.gif
< head  runat ="server" >
None.gif    
< title > 扩展 TreeView 实现选择 CheckBox 自动回发 </ title >
None.gif
</ head >
None.gif
< body >
None.gif    
< form  id ="form1"  runat ="server" >
None.gif    
< div >
None.gif        
< h1 > 扩展 TreeView 实现选择 CheckBox 自动回发 </ h1 >
None.gif        
< input  type ="button"  value ="Refresh"  onclick ="location.href=location.href"   />
None.gif        
< ddntest:XTreeView  id ="TreeView1"  runat ="server"  ShowCheckBoxes ="All"  OnTreeNodeCheckChanged ="TreeView1_TreeNodeCheckChanged" >
None.gif            
< Nodes >
None.gif                
< asp:TreeNode  Text ="1" >
None.gif                    
< asp:TreeNode  Text ="1.1"   >
None.gif                        
< asp:TreeNode  Text ="1.1.1"   ></ asp:TreeNode >
None.gif                    
</ asp:TreeNode >
None.gif                
</ asp:TreeNode >                 
None.gif                
< asp:TreeNode  Text ="2" >
None.gif                    
< asp:TreeNode  Text ="2.1"   >
None.gif                        
< asp:TreeNode  Text ="2.2.1"   ></ asp:TreeNode >
None.gif                    
</ asp:TreeNode >
None.gif                
</ asp:TreeNode >       
None.gif            
</ Nodes >
None.gif        
</ ddntest:XTreeView >     
None.gif        
< asp:Label  ID ="Label1"  runat ="server" ></ asp:Label >     
None.gif    
</ div >
None.gif    
</ form >
None.gif
</ body >
None.gif
</ html >
None.gif

测试效果


BTW,对于 AJAX 大肆流行的今天, PostBack 似乎大家都敬而远之,是否需要此功能,还是看个人应用实际需求了。

源码下载

相关文章:

  • 苏州印象
  • JS实现搜索关键字加亮效果
  • 使用redis做mybaties的二级缓存(2)-Mybatis 二级缓存小心使用
  • [转]SQL中CONVERT转化函数
  • 镜像ISO 小知识
  • Windows安装MySQL绿色版
  • 团队游戏2
  • cisco路由器配置及维护手册
  • Proxy设计模式
  • Lua第三方插件列表
  • Python2 爬虫(一) -- 人生第一条蠕动的爬虫
  • 人生就是这样
  • 当当开源sharding-jdbc,轻量级数据库分库分表中间件
  • 程序员必须掌握的基本正则表达式
  • ubuntu16.04安装mysql并配置远程访问
  • CSS 三角实现
  • Django 博客开发教程 16 - 统计文章阅读量
  • JavaScript异步流程控制的前世今生
  • JavaWeb(学习笔记二)
  • Joomla 2.x, 3.x useful code cheatsheet
  • JS数组方法汇总
  • Map集合、散列表、红黑树介绍
  • MQ框架的比较
  • React组件设计模式(一)
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Web Storage相关
  • 二维平面内的碰撞检测【一】
  • 解析 Webpack中import、require、按需加载的执行过程
  • 使用 QuickBI 搭建酷炫可视化分析
  • 算法-图和图算法
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 正则与JS中的正则
  • - 转 Ext2.0 form使用实例
  • Java总结 - String - 这篇请使劲喷我
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (39)STM32——FLASH闪存
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (接口自动化)Python3操作MySQL数据库
  • (强烈推荐)移动端音视频从零到上手(下)
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (转载)Linux网络编程入门
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .bat文件调用java类的main方法
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  • .NET构架之我见
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • 。Net下Windows服务程序开发疑惑
  • [1159]adb判断手机屏幕状态并点亮屏幕
  • [ASP]青辰网络考试管理系统NES X3.5
  • [autojs]autojs开关按钮的简单使用
  • [Avalon] Avalon中的Conditional Formatting.