?
以下是我自己写的一个TreeView控件代码:
using System;
using System.Text;
using System.Web.UI;
using System.Drawing;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.IO;
using WIM.Data;
using WIM.Data.Collections;
using WIM.BusinessFacade;
namespace WIM.WebControls
{
?? ///
?? /// TreeView 的摘要说明。
?? ///
?? [DefaultProperty("ID"), ToolboxData(" ")]
?? [Designer(typeof(TreeViewDesigner))]
?? public class TreeView : WIM.WebControls.ControlBase
?? {
????? #region 成员变量
????? private string m_SchemaName;
????? private string m_TreeCodeColumn;
????? private string m_ValueColumn;
????? private string m_TextColumn;
????? private string m_ChildClick;
????? private string m_ImageUrl;
????? private string m_DataValue;
????? private string m_RedirectUrl;
????? private string m_TargetFrame;
????? private bool m_IsClearTrack = true;
????? private int m_SelectIndex = -1;
????? private Doc m_DataSource;
????? private QueryConditionCollection m_DataQueryConditions;
????? private SortCondition m_DataSortCondition;
????? #endregion
????? #region 属性设置
????? ///
????? /// 架构名称
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue("ORG_Organ"),Description("架构名称")]
????? public string SchemaName
????? {
???????? get
???????? {
??????????? return m_SchemaName;
???????? }
???????? set
???????? {
??????????? m_SchemaName = value;
???????? }
????? }
????? ///
????? /// 编码列名
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue("TreeCode"),Description("编码列名")]
????? public string? TreeCodeColumn
????? {
???????? get
???????? {
??????????? return m_TreeCodeColumn;
???????? }
???????? set
???????? {
??????????? m_TreeCodeColumn = value;
???????? }
????? }
????? ///
????? /// 取值列名
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue("Id"),Description("取值列名")]
????? public string? ValueColumn
????? {
???????? get
???????? {
??????????? return m_ValueColumn;
???????? }
???????? set
???????? {
??????????? m_ValueColumn = value;
???????? }
????? }
????? ///
????? /// 显示列名
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue("Name"),Description("显示列名")]
????? public string? TextColumn
????? {
???????? get
???????? {
??????????? return m_TextColumn;
???????? }
???????? set
???????? {
??????????? m_TextColumn = value;
???????? }
????? }
????? ///
????? /// 单击事件
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(""),Description("单击事件")]
????? public string? ChildClick
????? {
???????? get
???????? {
??????????? return m_ChildClick;
???????? }
???????? set
???????? {
??????????? m_ChildClick = value;
???????? }
????? }
????? ///
????? /// 图片路径
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue("../images/OrganTree/"),Description("图片路径")]
????? public string? ImageUrl
????? {
???????? get
???????? {
??????????? return m_ImageUrl;
???????? }
???????? set
???????? {
??????????? m_ImageUrl = value;
???????? }
????? }
????? ///
????? /// 数据源文档对象
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(null),Description("数据源文档对象")]
????? public Doc DataSource
????? {
???????? get
???????? {
??????????? return m_DataSource;
???????? }
???????? set
???????? {
??????????? m_DataSource = value;
???????? }
????? }
?????
????? ///
????? /// 初始默认值
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(""),Description("初始默认值")]
????? public string DataValue
????? {
???????? get
???????? {
??????????? return m_DataValue;
???????? }
???????? set
???????? {
??????????? m_DataValue = value;
???????? }
????? }
????? ///
????? /// 单击节点时的连接地址
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(""),Description("单击节点时的连接地址。")]
????? public string RedirectUrl
????? {
???????? get
???????? {
??????????? return m_RedirectUrl;
???????? }
???????? set
???????? {
??????????? m_RedirectUrl = value;
???????? }
????? }
????? ///
????? /// 单击节点时的要重定向的目标对象名
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(""),Description("单击节点时的要重定向的目标对象名。")]
????? public string TargetFrame
????? {
???????? get
???????? {
??????????? return m_TargetFrame;
???????? }
???????? set
???????? {
??????????? m_TargetFrame = value;
???????? }
????? }
????? ///
????? /// 是否需要清除历史途径
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(true),Description("是否需要清除历史途径。")]
????? public bool IsClearTrack
????? {
???????? get
???????? {
??????????? return m_IsClearTrack;
???????? }
???????? set
???????? {
??????????? m_IsClearTrack = value;
???????? }
????? }
????? ///
????? /// 查询条件
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(null), Description("获取或设置获取数据时的查询条件")]
????? public QueryConditionCollection DataQueryConditions
????? {
???????? get
???????? {
??????????? if (m_DataQueryConditions == null)
??????????? {
?????????????? m_DataQueryConditions = new QueryConditionCollection();
??????????? }
??????????? return m_DataQueryConditions;
???????? }
???????? set
???????? {
??????????? m_DataQueryConditions = value;
???????? }
????? }
????? ///
????? /// 排序对象
????? ///
????? [Bindable(true), Category("WIM"), DefaultValue(null), Description("获取或设置获取数据时的排序对象")]
????? public SortCondition DataSortCondition
????? {
???????? set
???????? {
??????????? m_DataSortCondition = value;
???????? }
???????? get
???????? {
??????????? return m_DataSortCondition;
???????? }
????? }
????? #endregion
#region 主体呈现
????? ///
????? /// 将此控件呈现给指定的输出参数。
????? ///
????? /// 要写出到的 HTML 编写器
????? protected override void Render(HtmlTextWriter output)
????? {
???????? PlaceHolder control = new PlaceHolder();
???????? control.Page = this.Page;
???????? this.EnableViewState = false;
???????? this.InitParameter();
???????? Literal literal = new Literal();
???????? literal.Text = this.TreeHtml();
???????? control.Controls.Add(literal);
???????? //添加隐藏控件
???????? BaseFunction basFun = new BaseFunction();
???????? HtmlInputHidden hVal = basFun.CreaHid(ID, m_DataValue);
???????? control.Controls.Add(hVal);
???????? HtmlInputHidden hTxt = basFun.CreaHid(ID + "Text", "");
???????? control.Controls.Add(hTxt);
???????? //输出公共脚本块
???????? control.Page.RegisterStartupScript("TreeViewPublic", this.BuildPublicScript());
???????? //输出私有脚本
???????? control.Page.RegisterStartupScript(ID+"Script", this.BuildPrivateScript());
???????? control.RenderControl(output);
????? }
????? #endregion
????? #region 变量初始化
????? private void InitParameter()
????? {
???????? if ((m_TreeCodeColumn == null) || (m_TreeCodeColumn == ""))
???????? {
??????????? m_TreeCodeColumn = "TreeCode";
???????? }
???????? if ((m_TextColumn == null) || (m_TextColumn == ""))
???????? {
??????????? m_TextColumn = "Name";
???????? }
???????? if ((m_ValueColumn == null) || (m_ValueColumn ==""))
???????? {
??????????? m_ValueColumn = "Id";
???????? }
???????? if ((m_SchemaName == null) || (m_SchemaName == ""))
???????? {
??????????? m_SchemaName = "ORG_Organ";
???????? }
???????? if ((m_ImageUrl == null) || (m_ImageUrl == ""))
???????? {
??????????? m_ImageUrl = "../images/OrganTree/";
???????? }
???????? if ((m_ChildClick == null) || (m_ChildClick == ""))
???????? {
??????????? m_ChildClick = "";
???????? }
???????? if ((m_RedirectUrl == null) || (m_RedirectUrl == ""))
???????? {
??????????? m_RedirectUrl = "";
???????? }
???????? if ((m_TargetFrame == null) || (m_TargetFrame == ""))
???????? {
??????????? m_TargetFrame = "self";
???????? }
???????? if (this.m_DataSource == null)
???????? {
??????????? m_DataSource = this.GetDataSource(m_SchemaName);
???????? }
????? }
????? private Doc GetDataSource(string schemaName)
????? {
???????? DocManagement dm = new DocManagement(UserSessionId);
???????? Doc result = dm.GetDoc(m_SchemaName, "View", m_DataSortCondition, m_DataQueryConditions);
???????? return result;
????? }
????? #endregion
????? #region 主体函数
????? ///
????? /// 取得树结构的代码
????? ///
????? ///
????? private string TreeHtml()
????? {
???????? StringBuilder html = new StringBuilder();
???????? // 连线类型
???????? string lineStyle;
???????? // 叶子节点类型
???????? string leafStyle;
???????? // 当前节点的层次
???????? int level = 0;
???????? // 运行时记录当前层次的子节点总数
???????? int [] levelSonNumberList = new int[52];
???????? // 运行时记录当前层次的子节点记数
???????? int [] levelSonCounterList = new int[52];
???????? // 获取菜单的EntityTable对象
???????? EntityTable table = this.m_DataSource.EntityTable;
???????? // 记录菜单的子节点数(重新计算后的结果)
???????? int [] sonNumberList = RecalculateParentNumber(table, this.m_TreeCodeColumn);
???????? // 初始化数值
???????? for (int i = 0; i < 52; i ++)
???????? {
??????????? levelSonNumberList[i] = 0;
??????????? levelSonCounterList[i] = 0;
???????? }
???????? for (int i = 0; i < table.Entitys.Count; i ++)
???????? {
??????????? WIM.Data.Entity item = table.Entitys[i];
??????????? // 计算菜单层次
??????????? level = item[this.m_TreeCodeColumn].Value.Length / 4;
??????????? // 记录当前层的子节点数
??????????? levelSonNumberList[level] = sonNumberList[i];
??????????? // 设置当前层的子节点计数器
??????????? levelSonCounterList[level - 1] ++;
??????????? // 清空当前层之后的子节点数
??????????? // 清空当前层之后的子节点计数器
??????????? for (int j = level + 1; j < 52; j ++)
??????????? {
?????????????? levelSonNumberList[j] = 0;
?????????????? levelSonCounterList[j - 1] = 0;
??????????? }
??????????? // 指示节点是否显示
??????????? bool selected = false;
??????????? if (item[m_ValueColumn].Value == m_DataValue)
??????????? {
?????????????? this.m_SelectIndex = i;
?????????????? selected = true;
??????????? }
??????????? // 确定连接线的线型
??????????? lineStyle = "";
??????????? for (int j = 1; j < level; j ++)
??????????? {
?????????????? if (levelSonNumberList[j - 1] > levelSonCounterList[j - 1])
?????????????? {
????????????????? // 1类线:当前层仍然还有子节点(竖线)
????????????????? lineStyle += "1";
?????????????? }
?????????????? else
?????????????? {
????????????????? // 0类线:当前层没有子节点(空白)
????????????????? lineStyle += "0";
?????????????? }
??????????? }
??????????? // 确定目录和叶子的类型
??????????? if (sonNumberList[i] == 0)
??????????? {
?????????????? // 叶子
?????????????? if (levelSonNumberList[level - 1] == levelSonCounterList[level - 1])
?????????????? {
????????????????? // 叶级节点,并且之后没有兄弟节点(即最后一个子节点)
????????????????? leafStyle = "2";
?????????????? }
?????????????? else
?????????????? {
????????????????? // 叶级节点,并且之后还有其它的兄弟节点
????????????????? leafStyle = "3";
?????????????? }
??????????? }
??????????? else
??????????? {
?????????????? // 目录
?????????????? if (levelSonNumberList[level - 1] <= levelSonCounterList[level - 1])
?????????????? {
????????????????? // 目录节点,且还没有跳转到下一个上级节点
????????????????? leafStyle = "41";
?????????????? }
?????????????? else
?????????????? {
????????????????? // 目录节点,且已经跳转到下一个上级节点时
????????????????? leafStyle = "51";
?????????????? }
??????????? }
??????????? // 显示一个节点
??????????? html.Append(GetMenuItem(item, lineStyle, leafStyle, level, selected, m_ValueColumn, m_TextColumn, m_TreeCodeColumn, m_ImageUrl));
??????????? // 如果节点的儿子数不为0,则插入一个控制下级子菜单的层
??????????? if (sonNumberList[i] > 0)
??????????? {
?????????????? html.Append("
??????????? }
??????????? if ((levelSonNumberList[level - 1] == levelSonCounterList[level - 1]) && (sonNumberList[i] == 0))
??????????? {
?????????????? int k;
?????????????? try
?????????????? {
????????????????? if (i < table.Entitys.Count)
????????????????? {
???????????????????? k = table.Entitys[i + 1][m_TreeCodeColumn].Value.Length / 4;
????????????????? }
????????????????? else
????????????????? {
???????????????????? k = 0;
????????????????? }
?????????????? }
?????????????? catch
?????????????? {
????????????????? k = 0;
?????????????? }
?????????????? for (int j = k; j < level; j ++)
?????????????? {
????????????????? html.Append("
?????????????? }
??????????? }
???????? }
???????? return html.ToString();
????? }
///
????? /// 返回菜单项的HTML代码
????? ///
????? ///
????? ///
????? ///
????? ///
????? ///
????? ///
????? ///
????? ///
????? ///
????? ///
????? private string GetMenuItem(WIM.Data.Entity item, string lineStyle, string leafStyle, int level, bool selected, string valColumn, string txtColumn, string codeColumn, string imageUrl)
????? {
???????? StringBuilder inputHtml = new StringBuilder();
???????? inputHtml.Append(" ???????? inputHtml.Append(item[valColumn].Value);
???????? inputHtml.Append("/" treeCode=/"");
???????? inputHtml.Append(item[codeColumn].Value);
???????? inputHtml.Append("/" οnclick=/"");
???????? inputHtml.Append("selectItem(this)/"");
???????? if (selected)
???????? {
??????????? inputHtml.Append(" checked>");
???????? }
???????? else
???????? {
??????????? inputHtml.Append(">");
???????? }
???????? inputHtml = new System.Text.StringBuilder();
???????? StringBuilder html = new StringBuilder();
???????? html.Append("
???????? // 显示连接线和空白
???????? for (int i = 1; i < level; i ++)
???????? {
??????????? if (lineStyle.Substring(i - 1,1) == "1")
??????????? {
?????????????? html.Append("
???????? switch ( leafStyle)
???????? {
??????????? case "4":
??????????? case "5":
?????????????? html.Append("
???????? if ((leafStyle != "4") && (leafStyle != "41") && (leafStyle != "5") && (leafStyle != "51"))
???????? {
??????????? if ((leafStyle != "21") && (leafStyle != "31"))
??????????? {
?????????????? // 叶子节点
?????????????? html.Append("
?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(" style=/"display:''/" οnclick=/"javascript:clickItem(this,document.all.Imgc"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(",document.all.L"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(")/"> ?????????????? html.Append(".gif/"> ?????????????? html.Append(" style=/"display:'none'/" οnclick=/"javascript:clickItem(this,document.all.Imgo"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(",document.all.L"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(")/"> ?????????????? html.Append("1.gif/"> |
?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(" style=/"display:'none'/" οnclick=/"javascript:clickItem(this,document.all.Imgc"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(",document.all.L"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(")/"> ?????????????? html.Append(".gif/"> ?????????????? html.Append("/" style=/"display:''/" οnclick=/"javascript:clickItem(this,document.all.Imgo"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(",document.all.L"); ?????????????? html.Append(item[codeColumn].Value); ?????????????? html.Append(")/"> ?????????????? html.Append(".gif/"> |
?????????????? html.Append(".gif/"> |
?????????????? html.Append(".gif/"> |
"); ?????????????? // 插入CheckBox ?????????????? html.Append(inputHtml); ?????????????? html.Append("?????????????? html.Append(item[valColumn].Value); ?????????????? html.Append("','" + item[txtColumn].Value + "');"); ?????????????? html.Append(ID + "_SetHighlight(this)/">"); ?????????????? html.Append(item[txtColumn].Value); ?????????????? html.Append(" |
"); ?????????????? // 插入CheckBox ?????????????? html.Append(inputHtml); ?????????????? html.Append(""); ?????????????? html.Append(item[txtColumn].Value); ?????????????? html.Append(" |
"); ??????????? // 插入CheckBox ??????????? html.Append(inputHtml); ??????????? html.Append("??????????? html.Append(item[valColumn].Value); ??????????? html.Append("','" + item[txtColumn].Value + "');"); ??????????? html.Append(ID + "_SetHighlight(this)/">"); ??????????? html.Append(item[txtColumn].Value); ??????????? html.Append(" |
???????? return html.ToString();
????? }
????? ///
????? /// 重新计算父节点数
????? ///
????? ///
????? ///
????? ///
????? private int [] RecalculateParentNumber(WIM.Data.EntityTable table, string codeColumn)
????? {
???????? int [] sonNumberList = new int[table.Entitys.Count];
???????? int [] levelParentList = new int[50];
???????? for (int i = 0; i
???????? {
??????????? levelParentList[i] = 0;
???????? }
???????? for (int i = 0; i < sonNumberList.GetLength(0); i++)
???????? {
??????????? int level = table.Entitys[i][codeColumn].Value.Length / 4;
??????????? // 记下当前节点的所有上级的
??????????? levelParentList[level] = i;
??????????? // 每经过一个下级节点,就相当于上级节点自动累加1
??????????? sonNumberList[levelParentList[level - 1]] ++;
???????? }
???????? if (table.Entitys.Count > 0)
???????? {
??????????? sonNumberList[0] --;
???????? }
???????? return sonNumberList;
????? }
????? #endregion
?