public void SetStyle(ElementInitialStyle style) { // 本对象旧的状态 ExpandStyle oldChildExpand = this.m_childrenExpand; ExpandStyle oldAttrsExpand = this.m_attrsExpand; // 参数传进的新状态 ElementInitialStyle elementStyle = style; ExpandStyle newAttrsExpand = elementStyle.attrsExpandStyle; ExpandStyle newChildExpand = elementStyle.childrenExpandStyle; // 先设成不用改变状态 this.m_bWantAttrsInitial = 0; this.m_bWantChildInitial = 0; // 设属性是否需要改变状态 if (elementStyle.bReinitial == false) // 首次初始化 { this.m_bWantAttrsInitial = 1; } else { if (newAttrsExpand != oldAttrsExpand) this.m_bWantAttrsInitial = 1; else this.m_bWantAttrsInitial = 0; } // 设儿子状态 if (elementStyle.bReinitial == false) // 首次初始化 { this.m_bWantChildInitial = 1; } else { if (newChildExpand != oldChildExpand) this.m_bWantChildInitial = 1; else this.m_bWantChildInitial = 0; } }
// 根据xml编辑框中的内容创建后代 void BuildDescendant() { // 采用加虚根的方法 //this.SetFreshValue(); Debug.Assert(this.m_childrenExpand == ExpandStyle.Collapse, "不是闭合状态不要用本函数"); string strAdditionalNsString = ""; string strInnerXml = ""; // 2.得到attributes关闭时的text XmlText oText = this.GetContentText(); if (oText != null) { strInnerXml = oText.Text.Trim(); } else { Debug.Assert(false, "必须有text对象"); } NamespaceItemCollection nsColl = NamespaceItemCollection.GatherOuterNamespaces( (ElementItem)this); if (nsColl.Count > 0) { strAdditionalNsString = nsColl.MakeAttrString(); } string strXml = ""; if (this == this.m_document.VirtualRoot) { strXml = strInnerXml; } else { strXml = "<root "+ strAdditionalNsString + " >\r\n" + strInnerXml + "</root>"; } this.ClearChildren(); this.children = new ItemList(); XmlDocument dom = new XmlDocument(); dom.LoadXml(strXml); XmlNode root = null; if (this == this.m_document.VirtualRoot) { root = dom; } else { root = dom.DocumentElement; } foreach(XmlNode node in root.ChildNodes) { Item item = this.m_document.allocator.newItem(node, this.m_document); ElementInitialStyle style = new ElementInitialStyle(); style.attrsExpandStyle = ExpandStyle.Expand; style.childrenExpandStyle = ExpandStyle.Expand; style.bReinitial = false; item.Initial(node, this.m_document.allocator, style, true); // 这个函数是为Flush服务的函数,所以不应再使用时间戳加大 this.AppendChildInternal(item,false,true); } }
// expandAttrs 属性状态 // expandChildren 儿子状态 public void ExpandAttrsOrChildren(ExpandStyle expandAttrs, ExpandStyle expandChildren, bool bChangeDisplay) { bool bOldChanged = this.m_document.m_bChanged; //设光标为等待状态 Cursor cursorSave = this.m_document.Cursor; if (bChangeDisplay == true) { this.m_document.Cursor = Cursors.WaitCursor; } ElementInitialStyle style = new ElementInitialStyle(); style.childrenExpandStyle = expandChildren; style.attrsExpandStyle = expandAttrs; style.bReinitial = true; string strXml = ""; if (this == this.m_document.VirtualRoot) { strXml = this.GetOuterXml(null); } else { strXml = this.GetOuterXmlSpecial(); } XmlDocument dom = new XmlDocument (); try { dom.LoadXml(strXml); } catch(Exception ex) { throw(new Exception("ExpandChild()内部错误:" + ex.Message)); } if (this == this.m_document.VirtualRoot) { // 初始化item层次,注意使用根下的第一个元素 this.Initial(dom, this.m_document.allocator, style, true); } else { Debug.Assert(dom.DocumentElement.ChildNodes.Count == 1, "特殊的xml字符串doc根必须有且只有一个儿子"); // 初始化item层次,注意使用根下的第一个元素 this.Initial(dom.DocumentElement.ChildNodes[0], this.m_document.allocator, style, true); } // 重新初始化Visual层次 this.InitialVisual(); // 5.item重新layout,这里还用原来的rect,意思是item尺寸不变,主要修改里面的尺寸 int nRetWidth,nRetHeight; this.Layout (this.Rect.X, this.Rect.Y, this.Rect.Width, 0, this.m_document.nTimeStampSeed, out nRetWidth, out nRetHeight, LayoutMember.Layout); this.Layout(this.Rect.X, this.Rect.Y, this.Rect.Width, this.Rect.Height, this.m_document.nTimeStampSeed ++, out nRetWidth, out nRetHeight, LayoutMember.EnLargeHeight | LayoutMember.Up ); this.m_document.nTimeStampSeed++; /* if (this.SelectedItem != null) { // 如果CurItem1是element的属性之一 if (this.SelectedItem is AttrItem && this.SelectedItem.parent == element) { if (expandAttrs == ExpandStyle.Collapse) { this.SelectedItem = element; } } else { if (ItemUtil.IsBelong(this.SelectedItem, element)) { this.SelectedItem = element; } } } */ if (bChangeDisplay == true) { //layout后,文档尺寸发生变化,所以调此函数 this.m_document.AfterDocumentChanged(ScrollBarMember.Both); // 这儿为什么要这样做呢,我也不太清楚 this.m_document.DocumentOrgX = this.m_document.DocumentOrgX; this.m_document.DocumentOrgY = this.m_document.DocumentOrgY; //改回原来光标的状态 this.m_document.Cursor = cursorSave; this.m_document.m_bChanged = bOldChanged; this.m_document.Invalidate(); } //this.SelectedItem = element; this.m_childrenExpand = expandChildren; this.m_attrsExpand = expandAttrs; this.Flush(); }
// 用node初始化本对象和下级 // return: // -1 出错 // -2 中途cancel // 0 成功 public override int Initial(XmlNode node, ItemAllocator allocator, object style, bool bConnect) { // this.m_bConnected = true; this.m_bConnected = bConnect; // new change if (!(style is ElementInitialStyle)) { Debug.Assert(false,"style必须为ElementInitialStyle类型"); return -1; } if ((node.NodeType != XmlNodeType.Element) && node.NodeType != XmlNodeType.Document) { Debug.Assert(false, "'" + node.NodeType.ToString() + "'不是合适的节点类型"); return 0; } // 设状态 this.SetStyle((ElementInitialStyle)style); // 参数传进的新状态 ElementInitialStyle elementStyle = (ElementInitialStyle)style; ExpandStyle newAttrsExpand = elementStyle.attrsExpandStyle; ExpandStyle newChildExpand = elementStyle.childrenExpandStyle; // 初始化数据,从node中获取 this.InitialData(node); // 处理属性 if (this.m_bWantAttrsInitial == 1) { if (node.Attributes == null || node.Attributes.Count == 0) { this.m_attrsExpand = ExpandStyle.None; goto SKIPATTRS; } // 本次希望属性展开 if (newAttrsExpand == ExpandStyle.Expand) { this.ClearAttrs(); foreach(XmlNode attrXmlNode in node.Attributes ) { AttrItem attr = null; attr = (AttrItem)allocator.newItem(attrXmlNode, this.m_document); if (attr != null) { int nRet = attr.Initial(attrXmlNode, allocator, null, true); if (nRet == -1) return -1; this.AppendAttrInternal(attr,false,true); } attr.m_bConnected = true; } this.m_objAttrsTimestamp ++ ; this.m_attrsExpand = ExpandStyle.Expand; } else if (newAttrsExpand == ExpandStyle.Collapse) { // 注,收缩时不要把属性毁掉 // 本次希望属性收缩 this.m_attrsExpand = ExpandStyle.Collapse; } else { this.m_attrsExpand = ExpandStyle.None; } } SKIPATTRS: // 处理下级 if (this.m_bWantChildInitial == 1) { if (node.ChildNodes.Count == 0) //没有null的情况 { this.m_childrenExpand = ExpandStyle.None; goto SKIPCHILDREN; } // 希望下级展开 if (newChildExpand == ExpandStyle.Expand) { if (elementStyle.bReinitial == false || this.m_xmlChildrenTimestamp > this.m_objChildrenTimestmap) { this.ClearChildren(); // 处理下级 foreach(XmlNode child in node.ChildNodes) { Item item; item = allocator.newItem(child, this.m_document); if (item == null) continue; ElementInitialStyle childStyle = new ElementInitialStyle(); childStyle.attrsExpandStyle = ExpandStyle.Expand; childStyle.childrenExpandStyle = ExpandStyle.Expand; childStyle.bReinitial = false; int nRet = item.Initial(child, allocator, childStyle, bConnect); // 继承外面传入的参数 if (nRet == -2) return -2; if (nRet <= -1) { return nRet; } // 这里不在AppendChildInternal里做flush的原因是 // Initial()阶段表示只修改的一次,不是每个元素修改父亲一次 this.AppendChildInternal(item,false,true); //item.m_bConnected = true; } this.m_objChildrenTimestmap ++; } this.m_childrenExpand = ExpandStyle.Expand; } else if (newChildExpand == ExpandStyle.Collapse) { this.m_childrenExpand = ExpandStyle.Collapse; } else { this.m_childrenExpand = ExpandStyle.None; } } SKIPCHILDREN: /* // end ItemCreatedEventArgs args = new ItemCreatedEventArgs(); args.item = this; args.bInitial = true; this.m_document.fireItemCreated(this,args); */ return 0; }
// 专为供Xml属性设得私有函数 private void SetXml(string strXml) { strXml = strXml.Trim(); if (strXml == "") { if (this.VirtualRoot != null) { this.VirtualRoot.FireTreeRemoveEvents(this.VirtualRoot.GetXPath()); } this.VirtualRoot = null; this.docRoot = null; this.SetCurText(null,null); this.SetActiveItem(null); AfterDocumentChanged(ScrollBarMember.Both); this.Invalidate(); // 文档发生变化 this.FireTextChanged(); return; } if (this.VirtualRoot == null) { this.VirtualRoot = new VirtualRootItem(this); this.VirtualRoot.LayoutStyle = this.m_layoutStyle ; this.VirtualRoot.m_bConnected = true; } else { this.VirtualRoot.ClearAttrs(); this.VirtualRoot.ClearChildren(); } XmlDocument dom = new XmlDocument(); dom.PreserveWhitespace = true; dom.LoadXml(strXml); ElementInitialStyle style = new ElementInitialStyle(); style.attrsExpandStyle = ExpandStyle.Expand; style.childrenExpandStyle = ExpandStyle.Expand; style.bReinitial = false; this.VirtualRoot.Initial(dom,//dom.DocumentElement, allocator, style, true); this.docRoot = this.GetDocRoot(); this.VirtualRoot.InitialVisual(); int nWidth = 0; int nHeight = 0; this.VirtualRoot.Layout(0, 0, this.ClientSize .Width -1, 0 , nTimeStampSeed++, out nWidth, out nHeight, LayoutMember.Layout ); this.SetCurText(this.VirtualRoot,null); this.SetActiveItem(this.VirtualRoot); if (this.m_bFocused == true) this.curEdit.Focus(); AfterDocumentChanged(ScrollBarMember.Both); this.Invalidate(); // 文档发生变化 this.FireTextChanged(); }
// 用XML文本替代当前节点以及全部下级 // parameter: // strInputText 输入的即将用来粘贴的文本 // startItem 起始item public int PasteOverwrite(string strInputText, Item startItem, bool bSetFocus, out string strError) { strError = ""; if (String.IsNullOrEmpty(strInputText) == true) { Debug.Assert(false,"Paste(),strInputText为null 或者 空字符串"); strError = "Paste(),strInputText为null 或者 空字符串"; return -1; } if (startItem == null) { this.SetXml(strInputText); return 0; } if (startItem == this.VirtualRoot) { this.SetXml(strInputText); return 0; } // 根据startItem的类型,把输入的字符串拼成xml string strXml = ""; if (startItem is AttrItem) strXml = "<root " + strInputText + " />"; else strXml = "<root>" + strInputText + "</root>"; XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch(Exception ex) { strError = "paste() error,原因:" + ex.Message; return -1; } // item是新创建的临时元素 ElementItem item = new ElementItem(this); ElementInitialStyle style = new ElementInitialStyle(); style.attrsExpandStyle = ExpandStyle.Expand; style.childrenExpandStyle = ExpandStyle.Expand; style.bReinitial = false; item.Initial(dom.DocumentElement,this.allocator,style, false); // !!! // myParent是要覆盖的元素的父亲 ElementItem myParent = (ElementItem)startItem.parent; int nIndex = 0; bool bAttr = false; if (startItem is AttrItem) { bAttr = true; nIndex = myParent.attrs.IndexOf(startItem); Debug.Assert(nIndex != -1,"不可能的情况"); AttrItem startAttr = (AttrItem)startItem; foreach(AttrItem attr in item.attrs) { myParent.InsertAttrInternal(startAttr, attr, false, false); } myParent.RemoveAttrInternal(startAttr,false); } else { bAttr = false; // 找到startItem在myParent所有儿子中的索引位置 nIndex = myParent.children.IndexOf(startItem); Debug.Assert(nIndex != -1,"不可能的情况"); // 在startItem位置前面插入item的所有儿子 foreach(Item child in item.children) { // TODO: try // Exception: // 可能会抛出PrefixNotDefineException异常 myParent.InsertChildInternal(startItem, child, false, false); } // 删除startItem myParent.RemoveChildInternal(startItem,false); } myParent.InitialVisual(); int nWidth , nHeight; myParent.Layout(myParent.Rect.X, myParent.Rect.Y, myParent.Rect.Width, 0, //设为0,主要是高度变化 this.nTimeStampSeed++, out nWidth, out nHeight, LayoutMember.Layout | LayoutMember.Up); if (bSetFocus == true) { if (bAttr == true) { Item curItem = myParent.attrs[nIndex]; this.SetCurText(curItem,null); this.SetActiveItem(curItem); } else { Item curItem = myParent.children[nIndex]; this.SetCurText(curItem,null); this.SetActiveItem(curItem); } } else { this.SetCurText(this.m_selectedItem,this.m_curText); } // 可能会改变文档根, 重设一下 if (startItem.Parent == this.VirtualRoot) this.docRoot = this.GetDocRoot(); // 2006/6/22 xietao this.AfterDocumentChanged(ScrollBarMember.Both); this.Invalidate(); // 文档发生变化 this.FireTextChanged(); myParent.Flush(); return 0; }