标记 <ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="ScriptFiles" />,Mode="ScriptFiles" 是为了 MyTreePanel 呈现后,保证页面在正确的时机加载,并执行 MyCustomControl.MyTreePanel.init 方法,初始化其 tr 属性,以便在客户端操作该控件;
public const string SCOPE = "MyCustomControl.MyTreePanel"; 语句,配合脚本的 Ext.ns("MyCustomControl"); 以及 MyCustomControl.MyTreePanel = { … },在脚本创建命名空间和 MyTreePanel 类。
这种方式在很大程度上提高页面性能,便于日后维护该控件。
先看看封装后,在页面中引用自定义控件,代码如下:
代码如下 | 复制代码 |
<%@ Page Language="C#" %> <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %> <%@ Register Assembly="ExtNetTreePanleCustomControl" Namespace="ExtNetTreePanleCustomControl.MyCustomControl" TagPrefix="MyControl" %> <!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="ScriptFiles" />
<script src="resources/myTreePanel.js" type="text/javascript"></script>
</head> <body> <form id="form1" runat="server"> <ext:ResourceManager ID="ResourceManager1" runat="server" InitScriptMode="Linked" RemoveViewState="true" IDMode="Explicit" /> <MyControl:MyTreePanel ID="MyTreePanel1" runat="server" /> </form> </body> </html>
|
其中,"<MyControl:MyTreePanel ID="MyTreePanel1" runat="server" />" 是自定义的 TreePanel 控件。
自定义控件的分部类 MyTreePanel,文件名分别为 MyTreePanelLogic.cs 和 MyTreePanelUI.cs
代码如下 | 复制代码 |
using System; using System.Collections.Generic; using System.Linq; using Ext.Net.Utilities; using Ext.Net; namespace ExtNetTreePanleCustomControl.MyCustomControl { [DirectMethodProxyID(IDMode = DirectMethodProxyIDMode.None)] public partial class MyTreePanel { public const string SCOPE = "MyCustomControl.MyTreePanel"; private void InitLogic() { this.Listeners.Render.Fn = MyTreePanel.SCOPE + ".init"; this.Listeners.Render.Scope = MyTreePanel.SCOPE; this.Listeners.CheckChange.Handler = MyTreePanel.SCOPE + ".SelectParentChildNodes(node,checked);"; Ext.Net.Button button = new Ext.Net.Button(); button.ID = "btnGet"; button.Text = "获得勾选"; button.Listeners.Click.Handler = MyTreePanel.SCOPE + ".getSelectedNode(#{" + this.ID + "})"; this.Buttons.Add(button); button = new Ext.Net.Button(); button.ID = "btnClear"; button.Text = "清除勾选"; button.Listeners.Click.Handler = MyTreePanel.SCOPE + ".clearSelectedNode(#{" + this.ID + "})"; this.Buttons.Add(button); } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Xml.Serialization; using Ext.Net; using Newtonsoft.Json;
namespace ExtNetTreePanleCustomControl.MyCustomControl { public partial class MyTreePanel : TreePanel { public MyTreePanel() { this.ID = "MyTreePanel1"; this.Title = "MyTreePanel"; this.Width = System.Web.UI.WebControls.Unit.Pixel(300); this.Height = System.Web.UI.WebControls.Unit.Pixel(400); this.UseArrows = true; this.AutoScroll = true; this.Animate = true; this.EnableDD = true; this.ContainerScroll = true; this.RootVisible = false;
this.LoadMask.ShowMask = true;
this.SelectionModel.Add(new Ext.Net.DefaultSelectionModel());
this.BuildTree(); this.InitLogic(); }
private void BuildTree() { Ext.Net.TreeNode root = new Ext.Net.TreeNode("Composers"); root.Expanded = true; this.Root.Add(root);
List<Composer> composers = MyData.GetData();
foreach (Composer composer in composers) { Ext.Net.TreeNode composerNode = new Ext.Net.TreeNode(composer.Name, Icon.UserGray); composerNode.Checked = Ext.Net.ThreeStateBool.False; composerNode.Leaf = false; composerNode.Icon = Ext.Net.Icon.Folder; root.Nodes.Add(composerNode);
foreach (Composition composition in composer.Compositions) { Ext.Net.TreeNode compositionNode = new Ext.Net.TreeNode(composition.Type.ToString()); compositionNode.Checked = Ext.Net.ThreeStateBool.False; compositionNode.Leaf = false; compositionNode.Icon = Ext.Net.Icon.Folder; composerNode.Nodes.Add(compositionNode);
foreach (Piece piece in composition.Pieces) { Ext.Net.TreeNode pieceNode = new Ext.Net.TreeNode(piece.Title, Icon.Music); pieceNode.Checked = Ext.Net.ThreeStateBool.False; pieceNode.Leaf = true; compositionNode.Nodes.Add(pieceNode); } } } } } } |
数据
代码如下 | 复制代码 |
using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Web; using System.Xml; using Ext.Net;
namespace ExtNetTreePanleCustomControl { public class Composer { public Composer(string name) { this.Name = name; } public string Name { get; set; }
private List<Composition> compositions; public List<Composition> Compositions { get { if (this.compositions == null) { this.compositions = new List<Composition>(); } return this.compositions; } } }
public class Composition { public Composition() { }
public Composition(CompositionType type) { this.Type = type; }
public CompositionType Type { get; set; }
private List<Piece> pieces; public List<Piece> Pieces { get { if (this.pieces == null) { this.pieces = new List<Piece>(); } return this.pieces; } } }
public class Piece { public Piece() { }
public Piece(string title) { this.Title = title; }
public string Title { get; set; } }
public enum CompositionType { Concertos, Quartets, Sonatas, Symphonies }
public class MyData { public static List<Composer> GetData() { Composer beethoven = new Composer("Beethoven");
Composition beethovenConcertos = new Composition(CompositionType.Concertos); Composition beethovenQuartets = new Composition(CompositionType.Quartets); Composition beethovenSonatas = new Composition(CompositionType.Sonatas); Composition beethovenSymphonies = new Composition(CompositionType.Symphonies);
beethovenConcertos.Pieces.AddRange(new List<Piece> { new Piece{ Title = "No. 1 - C" }, new Piece{ Title = "No. 2 - B-Flat Major" }, new Piece{ Title = "No. 3 - C Minor" }, new Piece{ Title = "No. 4 - G Major" }, new Piece{ Title = "No. 5 - E-Flat Major" } });
beethovenQuartets.Pieces.AddRange(new List<Piece> { new Piece{ Title = "Six String Quartets" }, new Piece{ Title = "Three String Quartets" }, new Piece{ Title = "Grosse Fugue for String Quartets" } });
beethovenSonatas.Pieces.AddRange(new List<Piece> { new Piece{ Title = "Sonata in A Minor" }, new Piece{ Title = "sonata in F Major" } });
beethovenSymphonies.Pieces.AddRange(new List<Piece> { new Piece{ Title = "No. 1 - C Major" }, new Piece{ Title = "No. 2 - D Major" }, new Piece{ Title = "No. 3 - E-Flat Major" }, new Piece{ Title = "No. 4 - B-Flat Major" }, new Piece{ Title = "No. 5 - C Minor" }, new Piece{ Title = "No. 6 - F Major" }, new Piece{ Title = "No. 7 - A Major" }, new Piece{ Title = "No. 8 - F Major" }, new Piece{ Title = "No. 9 - D Minor" } });
beethoven.Compositions.AddRange(new List<Composition>{ beethovenConcertos, beethovenQuartets, beethovenSonatas, beethovenSymphonies });
Composer brahms = new Composer("Brahms");
Composition brahmsConcertos = new Composition(CompositionType.Concertos); Composition brahmsQuartets = new Composition(CompositionType.Quartets); Composition brahmsSonatas = new Composition(CompositionType.Sonatas); Composition brahmsSymphonies = new Composition(CompositionType.Symphonies);
brahmsConcertos.Pieces.AddRange(new List<Piece> { new Piece{ Title = "Violin Concerto" }, new Piece{ Title = "Double Concerto - A Minor" }, new Piece{ Title = "Piano Concerto No. 1 - D Minor" }, new Piece{ Title = "Piano Concerto No. 2 - B-Flat Major" } });
brahmsQuartets.Pieces.AddRange(new List<Piece> { new Piece{ Title = "Piano Quartet No. 1 - G Minor" }, new Piece{ Title = "Piano Quartet No. 2 - A Major" }, new Piece{ Title = "Piano Quartet No. 3 - C Minor" }, new Piece{ Title = "Piano Quartet No. 3 - B-Flat Minor" } });
brahmsSonatas.Pieces.AddRange(new List<Piece> { new Piece{ Title = "Two Sonatas for Clarinet - F Minor" }, new Piece{ Title = "Two Sonatas for Clarinet - E-Flat Major" } });
brahmsSymphonies.Pieces.AddRange(new List<Piece> { new Piece{ Title = "No. 1 - C Minor" }, new Piece{ Title = "No. 2 - D Minor" }, new Piece{ Title = "No. 3 - F Major" }, new Piece{ Title = "No. 4 - E Minor" } });
brahms.Compositions.AddRange(new List<Composition>{ brahmsConcertos, brahmsQuartets, brahmsSonatas, brahmsSymphonies });
Composer mozart = new Composer("Mozart");
Composition mozartConcertos = new Composition(CompositionType.Concertos);
mozartConcertos.Pieces.AddRange(new List<Piece> { new Piece{ Title = "Piano Concerto No. 12" }, new Piece{ Title = "Piano Concerto No. 17" }, new Piece{ Title = "Clarinet Concerto" }, new Piece{ Title = "Violin Concerto No. 5" }, new Piece{ Title = "Violin Concerto No. 4" } });
mozart.Compositions.Add(mozartConcertos);
return new List<Composer> { beethoven, brahms, mozart }; } } } |
外部脚本文件 myTreePanel.js
代码如下 | 复制代码 |
Ext.ns("MyCustomControl");
// ------------------MyTreePanel---------------------------------- MyCustomControl.MyTreePanel = { 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 != 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(tree) { 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(tree) { tree.clearChecked(); } }; |
运行结果如下