Ext.Net 1.2.0_在程序集中自定义 TreePanel 控件,并用反射动态获得数据源

本文介绍如何使用Ext.Net在Web应用中自定义TreePanel控件。通过创建包含UI和逻辑代码的分部类及外部脚本文件,实现动态加载树形结构数据,并支持客户端事件。演示了使用反射获取不同数据源构造树形结构的方法。
摘要由CSDN通过智能技术生成

本文内容

  • 概述
  • 演示在程序集中自定义 TreePanel 控件
  • 运行结果

 

概述

  • 博文 Ext.Net_在 Web 应用程序中自定义 TreePanel 控件。演示如何用 Ext.Net 在 Web 应用程序中自定义 TreePanel 控件。自定义的 TreePanel 控件由两个文件、三部分组成:控件的类文件和外部脚本文件。其中,控件类文件是一个分部类,分别实现控件的 UI 代码和逻辑代码。UI 代码负责创建控件标记;逻辑代码创建控件的客户端事件和服务器端事件。外部脚本文件用于在客户端操作控件。
  • 博文 Ext.Net_在程序集中自定义 TreePanel 控件Ext.Net_在 Web 应用程序中自定义 TreePanel 控件演示的类和脚本文件都在 Web 应用程序中。而该演示类和脚本都在程序集中,并把脚本文件作为程序集的嵌入资源,在 Web 应用程序中,通过 WebResource 方式引入。

本文的演示与 Ext.Net_在程序集中自定义 TreePanel 控件 的唯一区别是,后者创建树形结构的数据源是固定的,而前者是通过反射类中的方法动态获得。如下所示:

<MyExtNet:TreePanel ID="TreePanel1" runat="server" CustomFullName="MyExtNet.MyControl.DataBase"
    CustomMethod="GetData" CustomParams="-1" Width="200px" Height="300px" AutoScroll="true"
    Lines="false">
</MyExtNet:TreePanel>

其中,

  • TreePanel1 控件为自定义控件;
  • CustomFullName 属性是类全名,即程序集命名空间+类名;
  • CustomMethod 属性是类的方法;
  • CustomParams 属性是类中方法的参数。

 

演示在程序集中自定义 TreePanel 控件

解决方案结构

解决方案结构

自定义 TreePanel UI
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Ext.Net;
using System.Reflection;
using System.Data;
 
namespace MyExtNet.MyControl
{
    public partial class TreePanel : Ext.Net.TreePanel
    {
        private DataTable dataSource;
 
        [DefaultValue("")]
        [Description("自定义程序集)")]
        public string CustomFullName
        {
            get
            {
                return (string)this.ViewState["CustomFullName"] ?? "";
            }
            set { this.ViewState["CustomFullName"] = value; }
        }
        [DefaultValue("")]
        [Description("自定义方法名")]
        public string CustomMethod
        {
            get
            {
                return (string)this.ViewState["CustomMethod"] ?? "";
            }
            set { this.ViewState["CustomMethod"] = value; }
        }
        [DefaultValue("-1")]
        [Description("自定义方法的参数列表,逗号分隔")]
        public string CustomParams
        {
            get
            {
                return (string)this.ViewState["CustomParams"] ?? "";
            }
            set { this.ViewState["CustomParams"] = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        [DefaultValue(true)]
        [Description("节点前是否有勾选框")]
        public bool CustomHasCheck
        {
            get
            {
                object obj = this.ViewState["CustomHasCheck"];
                return (obj == null) ? false : (bool)obj;
            }
            set { this.ViewState["CustomHasCheck"] = value; }
        }
 
        public TreePanel()
        {
            this.RootVisible = false;
            this.SelectionModel.Add(new Ext.Net.DefaultSelectionModel());
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
 
            this.GetDataSource();
            this.BuildTree();
            this.InitLogic();
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
 
            string webResource = this.ResourceManager.GetWebResourceUrl(this.GetType(), "MyExtNet.MyControl.Resources.myTreePanel.js");
            this.ResourceManager.RegisterClientScriptInclude(string.Format("{0}_Script", MyExtNet.MyControl.TreePanel.SCOPE), webResource);
        }
        /// <summary>
        /// 创建树形结构 TreePanel
        /// </summary>
        protected void BuildTree()
        {
            if (this.dataSource == null)
            {
                throw new NullReferenceException();
            }
 
            TreeNode topNode = new TreeNode();
            topNode.NodeID = "0";
            topNode.Text = "Root";
 
            DataRow[] items = dataSource.Select("ParentID=" + this.CustomParams);
            if (items != null && items.Length > 0)
            {
                DataSet ds = new DataSet();
                ds.Merge(items);
                DataTable SourseTable = ds.Tables[0];
 
                for (int i = 0; i < SourseTable.Rows.Count; i++)
                {
                    TreeNode node = new TreeNode();
                    node.NodeID = SourseTable.Rows[i]["ID"].ToString();
                    node.Text = SourseTable.Rows[i]["NAME"].ToString();
                    DataRow[] isChildNode = dataSource.Select("parentid=" + SourseTable.Rows[i]["ID"].ToString());
                    // 父节点与子节点图标
                    if (isChildNode.Length > 0) node.Icon = Icon.FolderGo;
                    else node.Icon = Icon.Table;
                    // 父节点与子节点标记
                    if (isChildNode.Length <= 0) node.Leaf = true;
                    else node.Leaf = false;
 
                    if (!CustomHasCheck)
                    {
                        node.Checked = Ext.Net.ThreeStateBool.False;
                    }
 
                    topNode.Nodes.Add(node);
                    BuildTree(node, SourseTable.Rows[i]["ID"].ToString());
                }
            }
            this.Root.Add(topNode);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="TrNode"></param>
        /// <param name="parentID"></param>
        private void BuildTree(TreeNode TrNode, string parentID)
        {
            DataRow[] items = dataSource.Select("ParentID=" + parentID);
 
            if (items != null && items.Length > 0)
            {
                DataSet ds = new DataSet();
                ds.Merge(items);
                DataTable dt = ds.Tables[0];
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    TreeNode node = new TreeNode();
                    node.NodeID = dt.Rows[i]["ID"].ToString();
                    node.Text = dt.Rows[i]["NAME"].ToString();
                    DataRow[] isChildNode = dataSource.Select("parentid=" + dt.Rows[i]["ID"].ToString());
                    // 父节点与子节点图标
                    if (isChildNode.Length > 0) node.Icon = Icon.FolderGo;
                    else node.Icon = Icon.Table;
                    // 父节点与子节点标记
                    if (isChildNode.Length <= 0) node.Leaf = true;
                    else node.Leaf = false;
 
                    if (!CustomHasCheck)
                    {
                        node.Checked = Ext.Net.ThreeStateBool.False;
                    }
 
                    TrNode.Nodes.Add(node);
                    BuildTree(node, dt.Rows[i]["ID"].ToString());
 
                }
            }
        }
        /// <summary>
        /// 获得数据
        /// </summary>
        protected void GetDataSource()
        {
            if (this.CustomFullName.Length > 0 && this.CustomMethod.Length > 0)
            {
                Type type = null;
                type = this.CustomFullName.Substring(0, this.CustomFullName.LastIndexOf('.')) == this.GetType().ToString().Substring(0, this.GetType().ToString().LastIndexOf('.')) ?
                    Type.GetType(this.CustomFullName) : Assembly.Load(CustomFullName.Substring(0, this.CustomFullName.LastIndexOf('.'))).GetType(this.CustomFullName);
                MethodInfo method = type.GetMethod(this.CustomMethod);
                object value = null;
                if (method.IsStatic)
                    value = method.Invoke(null, null);
                else
                {
                    ConstructorInfo dataBaseC = type.GetConstructor(Type.EmptyTypes);
                    object dataBase = dataBaseC.Invoke(new object[] { });
                    value = method.Invoke(dataBase, null);
                }
                this.dataSource = (DataTable)value;
            }
        }
    }
}
自定义 TreePanel Logic
using System;
using Ext.Net.Utilities;
using Ext.Net;
 
namespace MyExtNet.MyControl
{
    [DirectMethodProxyID(IDMode = DirectMethodProxyIDMode.None)]
    public partial class TreePanel
    {
        public const string SCOPE = "MyExtNet.MyControl.TreePanel";
 
        private void InitLogic()
        {
            this.Listeners.Render.Fn = TreePanel.SCOPE + ".init";
            this.Listeners.Render.Scope = TreePanel.SCOPE;
            this.Listeners.CheckChange.Handler = TreePanel.SCOPE + ".SelectParentChildNodes(node,checked);";
 
            Ext.Net.Button button = new Ext.Net.Button();
            button.ID = "btnGet";
            button.Text = "获得勾选";
            button.Listeners.Click.Handler = TreePanel.SCOPE + ".getSelectedNode('" + this.ClientID + "')";
            this.Buttons.Add(button);
            button = new Ext.Net.Button();
            button.ID = "btnClear";
            button.Text = "清除勾选";
            button.Listeners.Click.Handler = TreePanel.SCOPE + ".clearSelectedNode('" + this.ClientID + "')";
            this.Buttons.Add(button);
        }
    }
}
自定义数据源,数据文件 MyData.xml 以及相应的类,包括非静态类 DataBase 和静态类 DataBaseStatic
  • 数据文件 MyData.xml
<?xml version="1.0" standalone="yes"?>
<data>
  <datas>
    <ID>208</ID>
    <CLASSID>195</CLASSID>
    <PARENTID>-1</PARENTID>
    <CODE>-1</CODE>
    <NAME>河北省</NAME>
    <CANCUSTOM>0</CANCUSTOM>
    <INSERTEDDATE>2011-10-25T10:36:16+08:00</INSERTEDDATE>
    <VALUE>130000</VALUE>
    <CHILDSTART>0.01</CHILDSTART>
    <CHILDEND>0.01</CHILDEND>
  </datas>
  <datas>
    <ID>213</ID>
    <CLASSID>195</CLASSID>
    <PARENTID>208</PARENTID>
    <CODE>-1</CODE>
    <NAME>邢台市</NAME>
    <CANCUSTOM>0</CANCUSTOM>
    <INSERTEDDATE>2011-10-25T10:38:23+08:00</INSERTEDDATE>
    <VALUE>130500</VALUE>
    <CHILDSTART>0.01</CHILDSTART>
    <CHILDEND>0.01</CHILDEND>
  </datas>
  <datas>
    <ID>210</ID>
    <CLASSID>195</CLASSID>
    <PARENTID>208</PARENTID>
    <CODE>-1</CODE>
    <NAME>唐山市</NAME>
    <CANCUSTOM>0</CANCUSTOM>
    <INSERTEDDATE>2011-10-25T10:37:09+08:00</INSERTEDDATE>
    <VALUE>130200</VALUE>
    <CHILDSTART>0.01</CHILDSTART>
    <CHILDEND>0.01</CHILDEND>
  </datas>
……
</data>
  • 非静态类 DataBase
using System;
using System.Data;
 
namespace MyExtNet.MyControl
{
 
    public class DataBase
    {
        public DataTable GetData()
        {
            DataSet ds = new DataSet();
            ds.ReadXml(AppDomain.CurrentDomain.BaseDirectory + "MyData.xml");
            DataTable dt = ds.Tables[0];
            return dt;
        }
    }
}
  • 静态类 DataBaseStatic
using System;
using System.Data;
 
namespace MyExtNet.MyControl
{
    public static class DataBaseStatic
    {
        public static DataTable GetData()
        {
            DataSet ds = new DataSet();
            ds.ReadXml(AppDomain.CurrentDomain.BaseDirectory + "MyData.xml");
            DataTable dt = ds.Tables[0];
            return dt;
        }
    }
}
自定义脚本 myTreePanel.js
Ext.ns("MyExtNet.MyControl");
 
MyExtNet.MyControl.TreePanel = {
    tr: null,
    init: function(tree) {
        this.tr = tree;
    },
    SelectParentChildNodes: function(node, state) {
        var tree = node.getOwnerTree();
        tree.suspendEvents();
        if (node.parentNode != null) {
            // 勾选该节点所有子节点
            node.cascade(function(node) {
                node.attributes.checked = state;
                node.ui.toggleCheck(state);
                return true;
            });
            // 勾选该节点父节点
            var pNode = node.parentNode;
            while (pNode.id != '0' && pNode != null) {
                if (state) { //如果选中状态无所谓
                    pNode.ui.toggleCheck(state);
                    pNode.attributes.checked = state;
                    pNode = pNode.parentNode;
                }
                else { //如果未选中状态,需要查看该节点是否所有子节点都未选中
                    var chk = false;
                    pNode.eachChild(function(child) {
                        if (child.attributes.checked || child.getUI().isChecked())
                            chk = true;
                    });
                    pNode.ui.toggleCheck(chk);
                    pNode.attributes.checked = chk;
                    pNode = pNode.parentNode;
                }
            }
        }
        tree.resumeEvents();
    },
    getSelectedNode: function(treeId) {
        var tree = Ext.getCmp(treeId);
        var msg = [];
        var selNodes = tree.getChecked();
 
        Ext.each(selNodes, function(node) {
            msg.push(node.text);
        });
 
        Ext.Msg.show({
            title: "勾选节点",
            msg: msg.join(','),
            icon: Ext.Msg.INFO,
            minWidth: 200,
            buttons: Ext.Msg.OK
        });
    },
    clearSelectedNode: function(treeId) {
        var tree = Ext.getCmp(treeId);
        tree.clearChecked();
    }
};
创建页面
<%@ Page Language="C#" %>
 
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<%@ Register Assembly="MyExtNet.MyControl" Namespace="MyExtNet.MyControl" TagPrefix="MyExtNet" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="Script" />
</head>
<body>
    <form id="form1" runat="server">
    <ext:ResourceManager ID="ResourceManager1" runat="server">
    </ext:ResourceManager>
    <div style="float: left">
        <MyExtNet:TreePanel ID="TreePanel1" runat="server" CustomFullName="MyExtNet.MyControl.DataBase"
            CustomMethod="GetData" CustomParams="-1" Width="200px" Height="300px" AutoScroll="true"
            Lines="false">
        </MyExtNet:TreePanel>
    </div>
    <div style="float: left">
        <MyExtNet:TreePanel ID="TreePanel2" runat="server" CustomFullName="MyExtNet.MyControl.DataBaseStatic"
            CustomMethod="GetData" CustomParams="-1" Width="200px" Height="300px" AutoScroll="true"
            Lines="false">
        </MyExtNet:TreePanel>
    </div>
    <div style="float: left">
        <MyExtNet:TreePanel ID="TreePanel3" runat="server" CustomFullName="MyExtNet.MyControl.DataBase"
            CustomMethod="GetData" CustomParams="208" Width="200px" Height="300px" AutoScroll="true"
            Lines="false">
        </MyExtNet:TreePanel>
    </div>
    </form>
</body>
</html>

其中,

  • ID 为 TreePanel1,反射非静态类中的方法,获得全部数据,构造树形结构;
  • ID 为 TreePanel2,反射静态类中的方法,获得全部数据,构造树形结构;
  • ID 为 TreePanel3,反射非静态类中的方法,获得所有父节点为 208 下的全部数据,构造树形结构。

 

运行结果

运行结果

其中,

  • 第一个图,为 TreePanel1;
  • 第二个图,为 TreePanel2;
  • 第三个图,为 TreePanel3。

 

下载 Demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值