小k的大师兄 发表于 2020-10-21 15:50:31

树形单元格

1.请问是否有树形单元格的例子?类似下图:
2.如果自己扩展一个树形单元格类型,是否可以不使用HTC来实现?

Richard.Ma 发表于 2020-10-21 18:06:30

1.目前没有树形单元格的类型和示例

2. 自定义单元格类型,可以通过继承GeneralCellType来实现,下面的链接是一个类似的博客,但是这个树状节点不是单元格里本身的,只供参考自定义单元格实现的思路

https://www.grapecity.com.cn/blo ... jiegouxianshifangan
这里还有另外一个介绍自定义单元格的教程
https://www.grapecity.com/blogs/ ... d-custom-cell-types

小k的大师兄 发表于 2020-10-22 08:46:19

我自己重写了一个树形下拉框单元格类型,但是在选择下拉值的时候无法选择,选值的时候好像页面又重新刷新了一次。如下图:

重新单元格类型代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Collections;
using System.Collections.Specialized;
using System.Web.UI;
using System.Web.UI.WebControls;

using FarPoint.Web.Spread;
using FarPoint.PDF;
using FarPoint.Web.Spread.Editor;
using FarPoint.Web.Spread.Model;
using FarPoint.Web.Spread.Renderer;
using System.Xml;

namespace JrscInfoSysEn.SpreadImp
{
    /// <summary>
    /// 树形下拉框
    /// </summary>
   
    public class TreeComboBoxCellType : GeneralCellType
    {
      /// <summary>
      /// 数据名称集合
      /// </summary>
      private string[] _Items;

      /// <summary>
      /// 数据值集合
      /// </summary>
      private string[] _Values;

      private int[] _Levels;

      /// <summary>
      /// 获取或设置数据名称集合
      /// </summary>
      public string[] Items
      {
            set
            {
                _Items = value;
            }
            get
            {
                return _Items;
            }
      }

      /// <summary>
      /// 获取或设置数据值集合
      /// </summary>
      public string[] Values
      {
            set
            {
                _Values = value;
            }
            get
            {
                return _Values;
            }
      }

      /// <summary>
      /// 获取或设置数据层级集合
      /// </summary>
      public int[] Levels
      {
            set
            {
                _Levels = value;
            }
            get
            {
                return _Levels;
            }
      }

      /// <summary>
      /// 初始化类TreeComboBoxCellType的新实例
      /// </summary>
      public TreeComboBoxCellType()
            : base()
      {

      }

      /// <summary>
      /// 获取用于编辑单元格的控件
      /// </summary>
      /// <param name="id">控件的唯一标识符</param>
      /// <param name="parent"></param>
      /// <param name="style"></param>
      /// <param name="margin"></param>
      /// <param name="value"></param>
      /// <param name="upperLevel"></param>
      /// <returns></returns>
      public override Control GetEditorControl(string id, TableCell parent, Appearance style, Inset margin, object value, bool upperLevel)
      {
            Label label = new Label();

            TreeView view = new TreeView();
            view.ImageSet = TreeViewImageSet.Arrows;
            view.BorderColor = System.Drawing.Color.CadetBlue;
            view.BorderStyle = BorderStyle.Solid;
            view.BorderWidth = 1;
            view.ShowExpandCollapse = true;
            view.ShowLines = true;
            view.Attributes.Add("style", "text-align :left");
            view.Height = new Unit(250);
            view.Width = new Unit("100%");
            view.Style.Add("overflow", "auto");
            view.BackColor = System.Drawing.Color.White;
            view.Font.Size = 9;
            view.HoverNodeStyle.Font.Bold = true;
            view.HoverNodeStyle.ForeColor = System.Drawing.Color.Blue;
            view.NodeStyle.ForeColor = System.Drawing.Color.Black;

            if (Items != null && Items.Length > 0)
            {
                CreateTreeView(view, Items, Values, Levels);
            }
            view.ExpandAll();

            Panel panel = new Panel();
            panel.Style.Add(HtmlTextWriterStyle.Cursor, "cursor");
            label.Controls.Add(panel);
            label.Controls.Add(view);

            Panel panel2 = new Panel();
            panel2.Style.Add(HtmlTextWriterStyle.Cursor, "cursor");

            label.Controls.Add(panel2);
            label.Style.Add(HtmlTextWriterStyle.ZIndex, "999");

            return label;
      }

      public override string EditorClientScriptUrl
      {
            get
            {
                var tt = base.EditorClientScriptUrl;
                return tt;
            }
      }

      /// <summary>
      /// 基于此类型派生单元格类型时,重写此选项可更改从数据模型中的对象传回并格式化为字符串的内容
      /// </summary>
      /// <param name="obj"></param>
      /// <returns></returns>
      public override string Format(object obj)
      {
            if (Values != null && Values.Length > 0)
            {
                for (int i = 0; i < Items.Length; i++)
                {
                  if (Values == obj.ToString().Trim())
                  {
                        return Items;
                  }
                }

                return null;
            }
            else
            {
                return base.Format(obj);
            }
      }

      /// <summary>
      /// 当基于此类型派生单元格类型时,重写此选项以更改从工作表上的单元格解析的内容并放入数据模型中。
      /// </summary>
      /// <param name="s"></param>
      /// <returns></returns>
      public override object Parse(string s)
      {
            if (string.IsNullOrEmpty(s))
            {
                return base.Parse(s);
            }

            if (Items != null && Items.Length > 0)
            {
                for (int i = 0; i < Items.Length; i++)
                {
                  if (Items == s.Trim())
                  {
                        return Values;
                  }
                }

                return null;
            }
            else
            {
                return base.Parse(s);
            }
      }

      /// <summary>
      /// 序列化
      /// </summary>
      /// <param name="xmlWriter"></param>
      /// <returns></returns>
      public override bool Serialize(XmlTextWriter xmlWriter)
      {
            xmlWriter.WriteStartElement("CellTypeAtrribute");
            if (Items == null)
            {
                xmlWriter.WriteElementString("ItemsCount", "0");
                xmlWriter.WriteEndElement();
            }
            else
            {
                xmlWriter.WriteElementString("ItemsCount", Items.Length.ToString());
                xmlWriter.WriteEndElement();
                xmlWriter.WriteStartElement("Items");
                for (int i = 0; i < Items.Length; i++)
                {
                  xmlWriter.WriteElementString("item", Items);
                  xmlWriter.WriteElementString("value", Values);
                  xmlWriter.WriteElementString("level", Levels.ToString());
                }
                xmlWriter.WriteEndElement();
            }

            return true;
      }

      /// <summary>
      /// 反序列化
      /// </summary>
      /// <param name="xmlReader"></param>
      /// <returns></returns>
      public override bool Deserialize(XmlNodeReader xmlReader)
      {
            xmlReader.ReadStartElement();
            int cnt = int.Parse(xmlReader.ReadElementString());
            xmlReader.ReadEndElement();

            if (cnt > 0)
            {
                xmlReader.ReadStartElement();
                Items = new string;
                Values = new string;
                Levels = new int;
                for (int i = 0; i < cnt; i++)
                {
                  _Items = xmlReader.ReadElementString();
                  _Values = xmlReader.ReadElementString();
                  _Levels = int.Parse(xmlReader.ReadElementString());
                }
                xmlReader.ReadEndElement();
            }

            return true;
      }

      /// <summary>
      /// 构造树形下拉框
      /// </summary>
      /// <param name="treeView">TreeView实例</param>
      /// <param name="strText">数据名称集合</param>
      /// <param name="strValue">数据值集合</param>
      /// <param name="iLevel">层级集合</param>
      private void CreateTreeView(TreeView treeView, string[] strText, string[] strValue, int[] iLevel)
      {
            if (strValue.Length == 0)
            {
                return;
            }

            treeView.Nodes.Clear();

            int _cnt = strValue.Length;
            int parentLevel = -1;
            TreeNode parentnode = null;
            if (_cnt > 0)
            {
                TreeNode node = new TreeNode();
                int level = iLevel;
                node.Text = strText;
                node.Value = strValue;
                parentLevel = level;
                treeView.Nodes.Add(node);

                parentnode = node;
            }

            for (int i = 1; i < _cnt; i++)
            {
                TreeNode node = new TreeNode();

                int level = iLevel;
                node.Text = strText;
                node.Value = strValue;

                int k = level - parentLevel;
                while (k <= 0)
                {
                  parentnode = parentnode.Parent as TreeNode;
                  k++;
                }

                if (parentnode == null)
                {
                  treeView.Nodes.Add(node);
                }
                else
                {
                  parentnode.ChildNodes.Add(node);
                }

                parentnode = node;
                parentLevel = level;
            }
      }
    }
}

Richard.Ma 发表于 2020-10-22 12:01:09

本帖最后由 Richard.Ma 于 2020-10-27 09:33 编辑

问题比较复杂,我这边正在和研发沟通解决办法,可能需要两三天的时间,然后给您回复

小k的大师兄 发表于 2020-10-27 13:27:17

你好 请问这个问题有办法解决吗?

Richard.Ma 发表于 2020-10-27 15:07:47

您好,还在研究解决方案,预计明天给您结果

小k的大师兄 发表于 2020-11-3 08:48:44

你好 请问你们研究出解决方案了吗? 如果实在不行 我们就考虑别的方式。谢谢!

Richard.Ma 发表于 2020-11-3 11:01:18

您好,非常抱歉,这个问题确实目前暂时没有办法解决。研发那边可能也需一些时间来验证,
问题的跟踪编号为SPNET-13342。如果有结果后我会及时更新

暂时来说,我建议你这边可以考虑先用下拉列表来进行替换。通过对下拉项的文本设置来模拟树状的效果

小k的大师兄 发表于 2020-11-3 11:38:51

好的 非常感谢 我们在采用别的方式处理 后续如果有相应的解决方案 麻烦告知一下 谢谢

Richard.Ma 发表于 2020-11-3 12:03:52

不客气
页: [1]
查看完整版本: 树形单元格