利用动态表单实现树形报表
1、先开发一张动态表单,放入树形控件和单据体
2、编写动态表单插件,示例代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.Base.PlugIn;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Contracts.Report;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;
using Kingdee.BOS.Util;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS;
using Kingdee.BOS.Core.Metadata.ControlElement;
using Kingdee.BOS.Core.Metadata.EntityElement;
using System.ComponentModel;
using System.Dynamic;
using System.Data;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.Bill;
namespace TreeNodeTest
{
public class TreeNodeTest : AbstractDynamicFormPlugIn
{
/// <summary>
/// 元数据
/// </summary>
private BusinessInfo _currInfo = null;
/// <summary>
/// 界面布局
/// </summary>
private LayoutInfo _currLayout = null;
/// <summary>
/// 初始化界面元数据时触发此事件
/// </summary>
/// <param name="e"></param>
/// <remarks>
/// 通常在此事件中,修改界面元数据;
/// 本示例,在此事件中,把界面元数据复制到本地,避免与其他实例公用元数据,造成串账
/// </remarks>
public override void OnSetBusinessInfo(SetBusinessInfoArgs e)
{
// 复制界面元数据到本地变量
FormMetadata currMeta = (FormMetadata)ObjectUtils.CreateCopy(
this.View.OpenParameter.FormMetaData);
_currInfo = currMeta.BusinessInfo;
_currLayout = currMeta.GetLayoutInfo();
// 用本地的元数据,替换动态表单引擎持有的元数据
e.BusinessInfo = _currInfo;
e.BillBusinessInfo = _currInfo;
}
/// <summary>
/// 初始化界面元数据时触发此事件
/// </summary>
/// <param name="e"></param>
/// <remarks>
/// 通常在此事件中,修改界面元数据;
/// 本示例,在此事件中,把界面元数据复制到本地,避免与其他实例公用元数据,造成串账
/// </remarks>
public override void OnSetLayoutInfo(SetLayoutInfoArgs e)
{
e.LayoutInfo = _currLayout;
e.BillLayoutInfo = _currLayout;
}
private HashSet<string> _loadedNodeIds = new HashSet<string>();
private Dictionary<string, NodeInfo> _dctNodes = new Dictionary<string, NodeInfo>();
public override List<TreeNode> GetTreeViewData(TreeNodeArgs e)
{
if (e.Key.Equals("F_PAEZ_TREEVIEW") == false)
{
// 需加载是其他树控件的节点,略过
return new List<TreeNode>();
}
// 加载全部节点信息到内存
//this.LoadNodes();
queryNodeComparny(0);
// 记录已经加载过根节点
this._loadedNodeIds.Add("0");
// 展开树控件节点
TreeView tv = this.View.GetControl<TreeView>("F_PAEZ_TreeView");
tv.SetExpanded(true);
// 构造根目录下的第一层节点并返回
List<TreeNode> nodes = this.BuildTreeNodes("0");
return nodes;
}
public override void TreeNodeClick(TreeNodeArgs e)
{
if (e.Key.Equals("F_PAEZ_TREEVIEW") == false)
{
// 点击的是其他树控件,略过
return;
}
// 判断是否已经加载过此节点的子节点,如果加载过,则不再加载
if (!this._loadedNodeIds.Contains(e.NodeId))
{
//return;
this._loadedNodeIds.Add(e.NodeId);
TreeView tv = this.View.GetControl<TreeView>("F_PAEZ_TREEVIEW");
string parentId = e.NodeId;
if (parentId.StartsWith("more"))
{// 当前点击的节点,是"点击加载更多..."
string[] keys = parentId.Split('|');
parentId = keys[1]; // 第2部分为父节点部分
// "点击加载更多..."节点已经被点击过,不再需要了,移除之
tv.RemoveNode(e.NodeId);
}
// 开始加载更多的子节点
List<TreeNode> childNodes = this.BuildTreeNodes(parentId);
if (childNodes.Count > 0)
{
tv.AddNodes(parentId, childNodes);
}
}
SetEntityData(e.NodeId);
}
private List<TreeNode> BuildTreeNodes(string parentId)
{
_dctNodes.Clear();
queryNodeComparny(Convert.ToInt32(parentId));
List<TreeNode> nodes = new List<TreeNode>();
// 遍历全部节点,找指定节点中,未加载的子节点的子节点
int count = 0;
int index = 0;
foreach (var item in _dctNodes)
{
NodeInfo nodeInfo = item.Value;
if (nodeInfo.Loaded == false
&& nodeInfo.ParentId == parentId)
{
nodeInfo.Loaded = true;
count++;
TreeNode node = new TreeNode()
{
id = nodeInfo.Id,
text = nodeInfo.Caption,
parentid = nodeInfo.ParentId,
};
nodes.Add(node);
}
index++;
}
return nodes;
}
private void queryNodeComparny(int nodeId)
{
int fid;
int parentId;
string node;
string sql = "select a.FID,b.FNAME,a.FPARENTID from T_BD_MATERIALGROUP a left join T_BD_MATERIALGROUP_L b on a.FID = b.FID where a.FPARENTID = '" + nodeId + "' order by a.FPARENTID ";
DataSet ds = Kingdee.BOS.ServiceHelper.DBServiceHelper.ExecuteDataSet(this.Context,sql);
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
fid = Convert.ToInt32(ds.Tables[0].Rows[i]["FID"].ToString());
parentId = Convert.ToInt32(ds.Tables[0].Rows[i]["FPARENTID"].ToString());
node = ds.Tables[0].Rows[i]["FNAME"].ToString();
_dctNodes.Add(fid.ToString(), new NodeInfo() { Id = fid.ToString(),ParentId = parentId.ToString(),Caption = node});
}
}
}
public void SetEntityData(string NodeId)
{
string Sql = "";
int FOriEntryCount = 0;
FOriEntryCount = this.View.Model.GetEntryRowCount("F_PAEZ_Entity");
if (FOriEntryCount > 0)
{
for (int i = FOriEntryCount - 1; i >= 0; i--)
{
this.View.Model.DeleteEntryRow("F_PAEZ_Entity", i);
}
}
Sql = "select a.FMATERIALID,a.FNUMBER,b.FNAME,b.FSPECIFICATION from T_BD_MATERIAL a left join T_BD_MATERIAL_L b on a.FMATERIALID = b.FMATERIALID ";
Sql += "where FMATERIALGROUP = '" + NodeId + "'";
DataSet ds = Kingdee.BOS.ServiceHelper.DBServiceHelper.ExecuteDataSet(this.Context,Sql);
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
this.View.Model.CreateNewEntryRow("F_PAEZ_Entity");
this.View.Model.SetValue("FMATID", ds.Tables[0].Rows[i]["FMATERIALID"].ToString(), i);
this.View.Model.SetValue("FMATNO", ds.Tables[0].Rows[i]["FNUMBER"].ToString(), i);
this.View.Model.SetValue("FMATNAME", ds.Tables[0].Rows[i]["FNAME"].ToString(), i);
this.View.Model.SetValue("FMODEL", ds.Tables[0].Rows[i]["FSPECIFICATION"].ToString(), i);
}
this.View.SetEntityFocusRow("F_PAEZ_Entity", 0);
}
}
}
public class NodeInfo
{
/// <summary>
/// 本节点Id
/// </summary>
public string Id { get; set; }
/// <summary>
/// 父节点Id
/// </summary>
public string ParentId { get; set; }
/// <summary>
/// 本节点标题
/// </summary>
public string Caption { get; set; }
/// <summary>
/// 是否已经加载标志:默认为false,未加载到前端
/// </summary>
public bool Loaded { get; set; }
}
}