12. juli 2004 - 21:38Der er
23 kommentarer og 2 løsninger
page_load og sender / System.EventArgs
Jeg har en mængde knapper på min web form. Når jeg klikker på en knap bliver clicked som sædvanligt opfanget af en event metode, eller hvad man nu kalder dem. Men jeg kunne godt tænke mig og vide om man kan finde ud af hvilken knap der er blevet klikket allerede i page_load metoden. altså istedet for at vente til man når ned til event metoden som skal fange den.
Du kan altid tjekke på om formen er submittet med page.IsPostback metoden.
Men som udgangspunkt er asp.net programmering event drevet, dvs. at den model man (for at overholde en rimelig god programmerings skik asp.net wise) bør bruge er netop den at et klik på en knap rejser en event, som man kan håndterer i en særskilt metode.
Man kan sagtens arbejde uden om den model, men det er ikke at anbefale, da koden vil være sværere at vedligeholde.
Jeg han nogle knapper der bliver lavet dynamisk, og når jeg klikker på en af dem, bliver der genereret nogle underknapper, som man så igen skal kunne klikke på. problemer med underknapperne er at deres eventhandling ikke virker, medmindre de bliver lavet i page_load. jeg ved ikke på forhånd hvor mange knapper der kommer.
Hvis nogen kan hjælpe med at løse problemet sætter jeg gerne 200points mere på spil. Kan du/nogen se andre måder at løse problemet på
nej bare gør det på din måde... så ser vi om jeg kan læse det...
Jeg har foresten rodet lidt med det selv, men sidder fast igen. Min kode kommer nedenfor, jeg har udeladet nogle metoder som ikke har med sagen at gøre: private void Page_Load(object sender, System.EventArgs e) { disableCaching(); makeTopButtons();
if (Session["pushedButtonID"] != null) { MakeLowerButtons((Int32)Session["pushedButtonID"], true); } }
private void makeTopButtons() { connectDB(); sql = "select topknapper from bla bla bla";
con.Open(); reader = QueryDB(sql); while (reader.Read()) { LinkButton button = new LinkButton(); button.CommandArgument = reader.GetString(0); button.Text = reader.GetString(1); button.Click += new EventHandler(this.Group_Selected); ButtonPlaceHolder.Controls.Add(button); ButtonPlaceHolder.Controls.Add(new LiteralControl(" ")); } reader.Close();
}
private MySqlDataReader QueryDB(String sql) { com = new MySqlCommand(sql, con); return com.ExecuteReader(); }
Som i nok opdager virker det fint nok indtil man begynder at springe rundt på top-knapperne og derefter trykker på en underknap.. label'en røber hvilken underknap du har trykket på...
ok... Du får lige lidt legerier her. Det er en lidt grotesk løsning, men måske finde noget interessant i det. Om ikke andet så underholdningsværdien :o)
Jeg vil gerne lave et lidt mere funktionelt eksempel, men prøv at se om du kan få det her til at køre :
Det er lavet så du i koden til din form kan styre hvilke knapper der sættes ind i hhv. top og subbuttons.
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls;
namespace chrede_sample { /// <summary> /// Summary description for chrede. /// </summary> public class chrede_sample : System.Web.UI.Page { protected Buttons[] buttonsArray;
// oprettelse af dummy-topbuttons int nob = 5; buttonsArray = new Buttons[nob]; for(int i=0 ; i<nob; i++) { buttonsArray[i] = new Buttons(); buttonsArray[i].ButtonClicked += new EventHandler(chrede_sample_ButtonClicked); buttonsArray[i].CreateButtons += new CreateButtonsEventHandler(chrede_sample_CreateButtons); buttonsArray[i].CreateSubButtons += new CreateSubButtonsEventHandler(chrede_sample_CreateSubButtons); } }
private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); }
// håndtere oprettelse af buttonarray til topbuttons private void chrede_sample_CreateButtons(object sender, CreateButtonsEventArgs e) { Button[] buttons = new Button[1];
buttons[0] = new Button(); buttons[0].Text = "TOP"; buttons[0].CommandName = "TOP";
e.Buttons = buttons; }
// håndterer oprettelse af buttonarray til subbuttons private void chrede_sample_CreateSubButtons(object sender, CreateButtonsEventArgs e) { Button[] buttons = new Button[3];
buttons[0] = new Button(); buttons[0].Text = "SUB"; buttons[0].CommandName = "SUB";
buttons[1] = new Button(); buttons[1].Text = "SUB"; buttons[1].CommandName = "SUB";
buttons[2] = new Button(); buttons[2].Text = "SUB"; buttons[2].CommandName = "SUB";
// ved angivelse af et buttonarray på argumentet, oprettes knapperne i kontrollen e.Buttons = buttons; }
// håndterer klik-evented. både for top og subbuttons private void chrede_sample_ButtonClicked(object sender, EventArgs e) { txtMessages.Text += ((Button)sender).CommandName + "\n"; } }
// delegetate ved oprettelse af topbuttons public delegate void CreateButtonsEventHandler(object sender, CreateButtonsEventArgs e);
// delegate til oprettelse af subbuttons public delegate void CreateSubButtonsEventHandler(object sender, CreateButtonsEventArgs e);
// argument ved oprettelse af knapper (både tops og subs) public class CreateButtonsEventArgs : System.EventArgs { private Button[] _buttons;
// array af knapper der indsættes hvis de angives i en handler et sted public Button[] Buttons { get{return _buttons;} set{_buttons = value;} } }
// public class Buttons : Control, INamingContainer { public event System.EventHandler ButtonClicked; public event CreateButtonsEventHandler CreateButtons; public event CreateSubButtonsEventHandler CreateSubButtons;
// property der gemmes i viewstate... angiver om subbuttons skal vises protected virtual bool ShowSubButtons { get { EnsureChildControls(); return (object)ViewState[this.UniqueID] != null ? (bool)ViewState[this.UniqueID] : false; } set{ViewState[this.UniqueID] = value;} }
// her indsættes de knapper der indskrives af en eventuel eventhandler af createbuttons-eventet protected override void OnInit(EventArgs e) { if(CreateButtons != null) { createButtonsEventArgs = new CreateButtonsEventArgs(); CreateButtons(this, createButtonsEventArgs); foreach(Button someButton in createButtonsEventArgs.Buttons) { Controls.Add(someButton); } }
base.OnInit (e); }
protected override void CreateChildControls() { Controls.Add(new LiteralControl("<br>")); SubButtons subButtons = new SubButtons(); subButtons.CreateButtons += new CreateButtonsEventHandler(subButtons_CreateButtons); Controls.Add(subButtons);
base.CreateChildControls (); }
// renderer kun subbuttons, hvis topknappen er "klikket ind" protected override void Render(HtmlTextWriter writer) { foreach(Control c in this.Controls) { if(!(c is SubButtons) || ShowSubButtons) c.RenderControl(writer); } }
// her bobler alle knaptryk så op... der divergeres mellem egne og subs protected override bool OnBubbleEvent(object source, EventArgs args) { if(((Control)source).NamingContainer == this) ShowSubButtons = (ShowSubButtons == false ? true : false);
// det er egentlig lidt klamt at have denne som en sub af den anden, men sjovt er det :o) public class SubButtons : Buttons, INamingContainer { protected override void CreateChildControls() { if(createButtonsEventArgs != null) { foreach(Button b in createButtonsEventArgs.Buttons) { Controls.Add(b); } Controls.Add(new LiteralControl("<br>")); } } } }
Og tag det nu ikke alt for alvorligt... Jeg ville bare gerne vise dig lidt omkring mulighederne med eventbubbling, egne delegates og argumenter. Det kan være nogle meget gode trix at have i ærmet nogle gange.
Nå - men alle alle knaptryk kan du i hvert fald håndtere i din page-klasse, men det har du så også selv fået til at virke kan jeg se. (jeg var vist lidt sent ude :o)
okay, jeg har lige læst din kode igennem, og jeg kan godt se at du er inde på det rigtige! ... problemet er bare at jeg er nybegynder i asp.net så jeg forstår ikke meget af din kode. Jeg er blandt andet ikke med på det med delegates (har aldrig arbejdet med det før) + flere andre ting.
Vil du hjælpe mig med at få min side til at virke som den skal? så vil jeg gerne give dig 200points.
Den skal ikke kunne meget mere end det du kan se i mit eksempel, knapperne skal bare virke efter hensigten + at jeg skal kunne skifte indeholdet af den nedeste placeholder ud (der hvor mine underknapper er). Hvis du vil hjælpe skal jeg nok uddybe det lidt bedre. Jeg vil blive meget glad hvis du vil hjælpe... :-) :-)
De øverste knappers "text" hentes fra en DB og de får også en ID med som skal bruges til at skabe underknapperne (også fra en DB). underknapperne har også et ID i db som igen skal bruges til at lave en mængde thumbnails (thumnails fil navne ligger i db og hentes vha. ID).
tanken i DB er følgende: et billede tilhører et galleri, et galleri tilhører en gruppe.
på siden er de øverste knapper grupper, når man vælger en gruppe kommer alle gallerier der tilhører gruppen, og når man vælger et galleri, ja så kommer alle thumbnails.
når siden loades første gang skal man bare se grupper (top knapperne), og det skal herefter være muligt at vælge frem og tilbage imellem dem. i dit eksempel smuttede "sub" knapperne hvis man trykkede atter en gang på "top" knappen... denne funktion er ligegyldig... man skal bare se de sub knapper der hører til en top knap, uanset hvor mange gange man klikker (ja, min mor har stadig ikke forstået at man ikke dobbeltklikker på hjemmeside) :-) :-)
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.