Avatar billede hadaps Nybegynder
19. marts 2006 - 09:40 Der er 26 kommentarer og
2 løsninger

event relay/bubbling

Hey

Er der en/nogle som har et færdigt eksempel på brug af enten event relay eller event ubbling? jeg har læst diverse artikler rundt omkring, men jeg ved ikke om det er fordi jeg sidder med .net 2.0 eller hvad der lige sker, for jeg kan ikke få nogle af dem til at spille :/
Hvis der er andre måder, hvorpå man kan samme flere knappers event i én (så man kun skal oprette ét object til at fange dem alle) så er jeg åben for input.
Jeg arbejder i asp.net 2.0 C#
Avatar billede dr_chaos Nybegynder
19. marts 2006 - 09:50 #1
noget med
<asp:Button id="btn1" runat=server OnClick="KnapTryk" text="Btn1" CommandName="Btn1" />
<asp:Button id="btn2" runat=server OnClick="KnapTryk" text="Btn2" CommandName="Btn2" />
<asp:Button id="btn3" runat=server OnClick="KnapTryk" text="Btn3" CommandName="Btn3" />

protected void KnapTryk(object sender, eventargs e)
{
Button Btn = sender as Button;

if(btn.CommandName == "Btn1")
{
//lav noget
}
else if(btn.CommandName == "Btn2")
{
//lav noget
}
else if(btn.CommandName == "Btn3")
{
//lav noget
}
}
Avatar billede hadaps Nybegynder
19. marts 2006 - 09:58 #2
men det kræver jo, at man initialisere alle knapper inden man kan fange deres event - det kan jeg ikke bruge til noget, da jeg har en rimelig regnetung rutine til at generere knapperne - derfor vil jeg gerne, at jeg kan nøjes med et oprette ét object, som fanger alle events fra én placeholder eller lign. og jeg dermed ikke skal generere knapperne igen bare for at modtage en event
Avatar billede dr_chaos Nybegynder
19. marts 2006 - 10:12 #3
så skal du bruge en repeater.
Den har et event som hedder itemcommand (eller noget i den stil) når man trykker på en knap i repeateren bliver den automatisk afviklet.
Avatar billede hadaps Nybegynder
19. marts 2006 - 10:15 #4
aha - er der ikke andre som også har den?
det virker lidt søgt, at bruge en repeater når det kun skla "gentages" én gang
Avatar billede dr_chaos Nybegynder
19. marts 2006 - 10:17 #5
måske.
Ellers er der en datalist.
Avatar billede driis Nybegynder
19. marts 2006 - 10:33 #6
Jævnfør:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconbubblingcommandevent.asp

Så er fremgangsmåden at lave en Control, som eksponerer en event der bruger Bubble mekansimen, og dernæst implementere handleren i en parent control, som fint kan være noget der arver fra f.eks. PlaceHolder. Som jeg læser det kan du ikke bruge nogen af de out-of-the box events der findes, men du skal definere din egen. Det behøver ikke være noget problem, idet du blot kan f.eks. definere BubbleClick og hooke den op i OnClick metoden; eller noget tilsvarende.

Jeg har ikke selv prøvet at bruge det før, men jeg vil gerne prøve at lave et eksempel, hvis du er interesseret.
Avatar billede driis Nybegynder
19. marts 2006 - 10:36 #7
Der er en lille fejl i ovenstående: Du kan godt bruge en af de indbyggede events direkte, du skal blot overide OnXXX og kalde RaiseBubbleEvent i denne. Den parent control der skal modtage bubble eventet skal så eksponere en passende event.
Avatar billede hadaps Nybegynder
19. marts 2006 - 10:38 #8
hmm... lyder interessant - Et eksempel er meget velkommen
Avatar billede driis Nybegynder
19. marts 2006 - 11:20 #9
Jeg fandt ud af at ASP .NET automatisk bubbler events, i hvert fald hvis de ikke bliver handlet.

Således behøver du kun at override OnBubbleEvent i den kontrol du bruger som parent, og sørge for at den rette event bliver kaldt - det kan enten være en event du definerer (Det vil jeg mene er pænest og mest fleksibelt), eller en event der allerede findes på kontrollen.
OnBubbleEvent skal returnere false hvis du ønsker at bubble eventet længere op i hierarkiet, eller true, hvis den ikke skal bubbles længere. Jeg foreslår at du blot kalder baseklassens OnBubbleEvent for at sikre at eventet bubbles videre efter ASP .NET's regler, hvis ikke du har handlet den.

Det leder os frem til flg. eksempel:
Avatar billede driis Nybegynder
19. marts 2006 - 11:23 #10
BubbleClickPlaceHolder klassen, som blot er en PlaceHolder som definerer en event BubbleClick som fyres af når der klikkes på en Button inde i PlaceHolderen:

using System;
using System.Web.UI.WebControls;

namespace BubbleTest
{

    /// <summary>
    /// Summary description for BubbleClickPlaceHolder
    /// </summary>
    public class BubbleClickPlaceHolder : PlaceHolder
    {
        public event EventHandler BubbleClick;

        protected override bool OnBubbleEvent(object source, EventArgs args)
        {
            if (source is Button && BubbleClick != null)
            {
                BubbleClick(source, args);
            }
           
            return base.OnBubbleEvent(source, args);
        }
    }
}

Eksempletes markup
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="bubble" Namespace="BubbleTest" %>
<!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>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <bubble:BubbleClickPlaceHolder runat="server" OnBubbleClick="Button_Click" ID="placeHolder">
            <asp:Button ID="button1" runat="server" Text="1" />
            <asp:Button ID="button2" runat="server" Text="2" />
            <asp:Button ID="button3" runat="server" Text="3" />
        </bubble:BubbleClickPlaceHolder>
    </div>
    </form>
</body>
</html>

Og endelig code-behind for eksemplet:
public partial class _Default : System.Web.UI.Page
{
    protected virtual void Button_Click(object sender, EventArgs e)
    {
        if (sender is Button)
            Response.Write("You clicked a button with Text=" + ((Button)sender).Text);
    }
}


Samme øvelse kan selvfølgelig udføres med andre events, f.eks. er det oplagt at køre det med Command, idet du så kan bruge CommandArgument til at overføre et-eller-andet argument til din handler. For at holde eksemplet simpelt har jeg dog holdt mig til Click eventet. Eneste forskel er at du vil være nødt at kaste args til en CommandEventArgs i din OnBubbleEvent metode.
Avatar billede hadaps Nybegynder
19. marts 2006 - 11:29 #11
hvor / hvilken fil siger du at BubbleClickPlaceHolder (det første) skal gemmes?
en .cs for sig selv eller?
Avatar billede hadaps Nybegynder
19. marts 2006 - 11:35 #12
never mind I got it - takker mange gange, så forstår jeg ligepludselig en del mare af artiklerne ;)
Avatar billede hadaps Nybegynder
19. marts 2006 - 11:48 #13
ough... når jeg så samler det i en usercontrol (.ascx) hvordan bobler jeg så events op til den side den bliver includeret på?
Avatar billede driis Nybegynder
19. marts 2006 - 12:14 #14
Umiddelbart burde det virke, ligegyldigt hvordan kontrollerne er arrangeret, blot den kontrol der skal håndtere eventet er parent (ét eller andet sted i hierarkiet) til den kontrol der genererer eventet.

Hvad præcist kan du ikke få til at virke ?
Avatar billede hadaps Nybegynder
19. marts 2006 - 12:17 #15
tror jeg bruger det forkert så :(
hvor meget skal ligge i:
<bubble:BubbleClickPlaceHolder runat="server" OnBubbleClick="Button_Click" ID="placeHolder"></bubble:BubbleClickPlaceHolder>

er det hele vejen op igennem hirakiet, eller kun i det lag hvor den skal serviceres?
Avatar billede hadaps Nybegynder
19. marts 2006 - 12:33 #16
oh... man skal så stadig genere alle controls som man vil fange events på?
det var jo ikke helt planen, planen var et det bare var selv "placeholder" man oprettede, og så alt hvad der blev sent igennem den ved postback blev fanget, når bare man havde oprettet placeholderen (og ingen indhold)
Avatar billede driis Nybegynder
19. marts 2006 - 12:36 #17
Du skal selvfølgelig selv generere alle controls, hvis der ikke findes nogen controls er der jo heller ingen events der kan raises. Men det kan selvfølgelig godt ske dynamisk.

Koden fra PlaceHolderen skal placeres dér hvor du ønsker at konsumere dit event, dvs. det godt kunne ligge i f.eks. din Page.
Avatar billede hadaps Nybegynder
19. marts 2006 - 12:39 #18
men dvs. at en fremgangsmåde kunne være, at genere en bunke dummy controls som man gemmer i bunden, så man altid har en pulje at tage af, og når algoritmen finder ud af, at den skal bruge en mere, flyttes den/dem op på plads?
Avatar billede driis Nybegynder
19. marts 2006 - 12:44 #19
Nej jeg ville genere dem dynamisk, noget i retning af:

for( int i = 0 ; i < 1000 ; i++ )
{
  // do stuff
  // ....
  if ( newControlRequired )
  {
    Button b = new Button();
    myPlaceHolder.Controls.Add(b);
  }
}

For-løkken er blot en illustration af at du laver et-eller-andet, der muligvis kræver en ny kontrol.
Avatar billede hadaps Nybegynder
19. marts 2006 - 12:44 #20
der hvor jeg sidder fast er, at jeg vil helst være fri for, at genere alle controls som de var, da siden blev sendt til client, bare for at modtage et event fra én af dem - men det kan jeg måske ikke slippe for?
Avatar billede hadaps Nybegynder
19. marts 2006 - 12:55 #21
Hvis fx tager denne:
protected void Page_Load(object sender, EventArgs e)
    {
            Button btn = new Button();
            btn.Visible = false;
           
        if (!IsPostBack)
        {
            btn.Text = "fisk";
            btn.CommandName = "gogogo";
            btn.Visible = true;
        } 
        fidk.Controls.Add(btn);
    }

-så kan jeg ikke hente Text og CommandName fra kanppen, og det vil jeg gerne kunne, for ellers skal jeg jo genere det hele 2 gange, en for at vise, og en for at fange event + diverse data
Avatar billede driis Nybegynder
19. marts 2006 - 13:01 #22
Jeg havde ikke fanget at det var det du ville opnå. Umiddelbart kender jeg ikke en ordentlig måde at gøre dette på - ASP .NET postback mekanisme arbejder jo netop ved at formfeltet __EVENTTARGET er sat til ClientID værdien for den kontrol, der genererede eventet - og hvis ASP .NET ikke kan finde den kontrol, ignoreres eventet blot.
Avatar billede hadaps Nybegynder
19. marts 2006 - 13:04 #23
aha - dejlig info ;)

men dvs. jeg endten skal generere siden 2 gange, eller droppe event?
har du guideline til hvad der er at foretrække?
Avatar billede hadaps Nybegynder
19. marts 2006 - 13:17 #24
jeg har fundet noget interessant her:
http://www.123aspx.com/redir.aspx?res=30376

men det er skrevet til asp.net 1.x
umiddelbart ville jeg mene det skulle være nogen lunde ligetil at omsætte den til 2.0, men åbentbart ikke for mig :(
Avatar billede hadaps Nybegynder
19. marts 2006 - 13:50 #25
er det noget du er frisk på at se til?
-er villig til at smide flere point efter dig
Avatar billede driis Nybegynder
19. marts 2006 - 14:31 #26
Man opbygger normalt siden 2 gange for at handle eventet. Det er ikke noget du skal være bekymret for, rent performance mæssigt.

Jeg har kun lige overfladisk kigget på dit link - umiddelbart tror jeg ikke at det er særligt brugbart i din situation.
Avatar billede hadaps Nybegynder
19. marts 2006 - 14:36 #27
hmmm... fair nok - men hvorfor betyder det ikke noget mht. performance?
cacher den siden? for hvis den laver alt db trylleriet igen, så er der da stor forskel
Avatar billede driis Nybegynder
19. marts 2006 - 16:17 #28
Selvfølgelig betyder det noget hvis du skal ned og læse fra databasen igen. På den anden side er det ofte så lidt at det ikke kan betale sig at optimere på det. Er det nødvendigt at optimere på det, har du jo chancen for at placere data eller objekter i Cache eller Session state første gang det læses.

EventRelay kontrollen du linker til fungerer ved at der køres noget clientside javascript, der forårsager postback med __EVENTTARGET = EventRelay kontrollen. Det kan godt bruges, men du skal være klar over at det ikke er det samme event du får - men blot en event der har en streng som argument, og hvor det ikke er muligt at referere til den kontrol, der rent faktisk generede eventet.

Jeg mener at metoden med at generere siden igen er den rigtige "the .NET way" og objektorienterde måde at gøre det på.
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester