27. maj 2006 - 19:50Der er
13 kommentarer og 1 løsning
TreeNode med buttons
Jeg vil gerne lave en TreeNode med x-antal buttons som udfører serverside kode. Jeg har lavet en klasse som arver fra TreeNode og ændret i RenderPreText-metoden således, at når noden bliver renderet så indeholder den en button.
public class MyTreeNode : TreeNode { protected override void RenderPreText(System.Web.UI.HtmlTextWriter writer) { Button btn = new Button(); btn.Text = "new button"; btn.ID = "btn1";
btn.CommandArgument = "test";
btn.RenderControl(writer); } }
Hvordan fanger jeg click-eventen fra button'en i treenoden?
Selve klassen MyTreeNode er placeret i en seperat .cs-fil. Kan jeg på nogen måde få adgang til de objekter der er placeret på siden default.aspx. Jeg tænker her på om jeg i min handler btn_Click kunne få adgang til label1.text og sætte den til "event fanget".
Mmmm.... Det kan du sådan set godt, men er det ikke nemmere blot at debugge, og se om du rammer din handler? Du er velkommen til at poste hele koden vedr. dit treeview - så prøver jeg det lige her. Mvh
Og selve def. af treeNoden, CustomTreeNode.cs: public class MyTreeNode : TreeNode, INamingContainer { protected override void RenderPreText(System.Web.UI.HtmlTextWriter writer) { Button btn = new Button(); btn.Text = "new button"; btn.Click += new EventHandler(btn_Click); btn.RenderControl(writer); }
Hvis du skal sikre at det er dine noder der bliver benyttet - må du specialisere et treeview også. Ellers vil din pretext forsvinde hvis du ikke generer dit treeview hver gang.
public class MyTreeView : TreeView { protected override TreeNode CreateNode() { return new MyTreeNode(); } }
Mht. til det med at håndtere events, så har jeg kigget lidt på det, og det er ikke helt så snildt som det måske kunne have været. Det er ikke nødvendigvis det hele du skal bruge, men hvis du vil have fat i den node knapklikket er fyret fra i din eventhandler - skal du lave noget meget tilsvarende: (Der er ikke noget aspx-kode).
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page { MyTreeView tree = null;
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { MyTreeNode n1 = new MyTreeNode(tree); n1.Text = "N1"; tree.Nodes.Add(n1);
MyTreeNode n2 = new MyTreeNode(tree); n2.Text = "N2"; n1.ChildNodes.Add(n2);
// Delegate for TreeButtonClick-eventhandlers public delegate void TreeButtonClickedEventHandler(object treeView, TreeButtonClickedEventArgs e);
// Specielt argment, så du har let adgang til noden der er klikket på public class TreeButtonClickedEventArgs : EventArgs { private TreeNode m_Node;
public TreeNode Node { get { return m_Node; } set { m_Node = value; } }
public TreeButtonClickedEventArgs(TreeNode node) { this.m_Node = node; } }
// Custom treeview - så du sikrer at dine egne noder bliver benyttet // Desuden publicerer det så ButtonClicked eventet public class MyTreeView : TreeView { public event TreeButtonClickedEventHandler ButtonClicked;
// protected override TreeNode CreateNode() { return new MyTreeNode(this); }
// Overskrivning af treeview'ets raisepostbackevent - så eget prefix kan håndteres. // Hvis det ikke er eget prefix der er benyttet - benyttes basens implementering. // Dette skal sikre at de vanlige event fyres. protected override void RaisePostBackEvent(string eventArgument) { if (eventArgument[0] == 'b') { string nodePath = eventArgument.Substring(1); TreeNode node = this.FindNode(nodePath); OnButtonClicked( new TreeButtonClickedEventArgs(node) ); } else { base.RaisePostBackEvent(eventArgument); } } }
// custom treenode - definerer sit eget kommandoprefix, så knapper kan kendes fra de andre kommandoer public class MyTreeNode : TreeNode { protected const string ButtonCommandPrefix = "b";
private TreeView m_Tree;
public TreeView Tree { get { return m_Tree; } set { m_Tree = value; } }
// I eksemplet her er det så et krav at din noder instantieres med et treeview, hvilet // er nødvendigt for at få fat i kontrollen (treeview'et) der skal håndtere kommandoen public MyTreeNode(TreeView tree) { m_Tree = tree; }
Du kan enten bare skrive det direkte - eller gøre denne her public: protected const string ButtonCommandPrefix = "b"; Så den bliver til public const string ButtonCommandPrefix = "b";
Så kan du få den uden for klassen ved at kalde: MyTreeNode.ButtonCommandPrefix;
Ja okay. Det jeg var interesseret i var at give de enkelte knapper et forskelligt prefix så jeg i tree_ButtonClicked kunne afgøre hvilken knap der blev trykket på. Så det var muligt at have flere knapper på den enkelte node. Var det ikke det der var meningen med ButtonCommandPrefix ?
Eventhåndtering er TreeView'et er (som det nu er bygget) baseret på prfixes på kommandoargumentet - 't' for toggle og 's' for select. Eksemplet du har fået bygger bare videre på samme model - men benytter blot et andet prefix på kommandoargumentet. Du kan arbejde med alle de prefixes du vil ... blot du ikke snupper dem treeview'et bruger i forvejen (altså t og s), eller bruger nogle der gør at der går kludder i udledning af hvilken node der er trykket på. Hvis du sætter et breakpoint i RaisePostBackEvent på MyTreeView - kan du se navnekonventionen for argumentet. Mvh
Jeg takker mange gange, virkeligt genialt. Send lige et svar. ps. Er det nemt at tilføje et input-felt i samme treenode og fange teksten i tree_ButtonClicked?
Det var så lidt :o) Det bliver nok lidt noget pilleri... En TreeNode er ikke nogen kontrol (Control), så den er lidt anderledes. Prøv at læg din textbox ind sådan her:
Jeg er ligeglad med at det ikke er labert! Det virker. Her er points fuldt fortjent. sensai
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.