I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
du kan bare indsætte en i din itemtemplate sådan her : (her et eksempel på en checkbox der er databundet til en kolonne i datakilden med navnet FldBool).
at du angiver id'et på kontrollen gør, at du lettere kan finde den senere... du kan f.eks. lave et loop over alle rækker, og hive værdien af checkboxen ud sådan her :
foreach(RepeaterItem ri in someRepeater.Items) { CheckBox cb = (CheckBox)ri.FindControl("chkCheck"); bool checked = cb.Checked; }
chkCheck bliver ikke det resulterende name i din html.... frameworket sikrer at dine id's bliver unikke (hvis du kigger på den resulterende html, er det reletivt let at se hvordan det foregår - ellers kan du bare spørge).
normalt vil du databinde en repeater til en eller anden form for liste - f.eks. et dataview, en datatable ell.
hiver du f.eks. noget data op i et dataset :
DataSet ds = someDal.GetData(...); kan du få renderet din repeater udfra de data du har hentet :
someRepeater.DataSource = ds.Tables[0]; // første tabel i datasættet someRepeater.DataBind();
okay jeg tror jeg har fået det til at virke. Nu vil jeg så gerne lave en "vælg alle" knap. MEn jeg ser dotnet gir dem et rimeligt underligt navn. Hvordan implementerer jeg nemmest sådan en vælg alle funktion?
Ja det har jeg. Undskyld snepnet. Jeg glemte at informere dig om at jeg er gået videre med at lave noget tilsvarende. Selectall løste jeg ved at lave et clientscript
Men problemet er at jeg har mine repeaters (jeg har 2 nestede) liggende på en usercontrol. Disse bliver dynamisk loadet ind i en placeholder alt afhængig af hvad brugeren vil se. Hver repeater gruppere data på en bestemt måde. Jeg har så en knap der hedder opret bestilling som ligger i min aspx fil. Når denne trykkes skal der så køres igennem alle checkboxes og oprettes bestillinger. Problemet er at jeg ikke kan få fat i min repeater da den jo ligger på den usercontrol der blev loadet ind på siden.
Så hvordan omgår jeg det problem? Undskyld hvis jeg udnytter din venlighed. Jeg skal nok give dig flere point...Bare nemmere lige at have det hele samlet her :)
bare iorden :o) det mest nærliggende er nok at du gør din repeater til en public property på din usercontrol - og så bare gafler den der.
public Repeater InternalRepeater { get{return this.internalRepeater;} }
ellers har du adgang til din usercontrols kontroller ved someUserControl.Controls[index på den du vil have fat];
men som sagt.... det lyder som om din interne repeater er en væsentlig del af dit interface til kontrollen, hvorfor det virker ok at lave bemeldte property.
hmmm men dvs. jeg skal oprette en instans af min usercontrol nede i eventhandleren eller hvad? Jeg kan ikke lige se hvordan jeg har adgang til mit usercontrolobjekt nede fra eventhandleren?
hvis du kun lægger én enkelt ind - kan du jo gemme referencen : Control c = LoadControl(...);
du også give den et id - hvorefter du nemmere kan finde den igen : Control c = LoadControl(...); c.ID = someId;
og i din handler : placeholder.FindControl(someId);
denne skal så castes til din usercontrol : SomeUserControl userControl = (SomeUserControl )placeholder.FindControl(someId);
og du kan så tilgå din repeater ved : userControl.InnerRepeater;
men .... nu ved jeg så ikke helt hvad det er du skal har brug for at oplysninger fra "innerrepeateren" ... hvis du f.eks. skal have en stak id's som er valgt ved checkboxen... kan du jo pakke lidt mere af funktionaliteten ind i din usercontrol, og hente dem direkte ved en property som int[] selectedIds = userControl.SelectedIds;
Burde den placeholder ikke blive oprettet automatisk? Og derved indhente de objekter der blev placeret i den i forrige serverroundtrip. Altså indhente dem via viewstatet?
den metoder bliver ikke kaldt fra eventhandleren...eller pageload. Så den bliver altså ikke kaldt overhovedet når man har trykket på opret knappen.. Øjeblik. Sender dig lige hele klassen:
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;
nej... dynamisk tilføjede kontroller skal tilføjes hver gang, men der findes komponenter du kan download gratis der hjælper med at "huske" de dynamisk indsatte kontroller - jeg finder lige et link her bagefter : Såhh... tilføjer du dem ikke hver gang, vil du heller ikke kunne finde dem igen. mvh
men nej - du kan ikke få fat i de checkboxe der er hakket af programmatisk hvis du loader en ny kontrol i din eventhandler. det vil jo bare være en ny instans af samme kontroltype - som aldrig er blevet renderet til brugeren. men ... jeg forstår stadig ikke helt hvorfor du ikke bare loader dem hver gang ? mvh
ALtså problemet er at det er en side hvor brugeren får en oversigt over alle hans automater. Han kan så hurtige oprette en bestilling på disse automater ved at hakke af i "vælg alle" checkboksen. Herefter trykker han på "opret bestilling" knappen hvorefter han skal ind på en side hvor alle disse bestillingslinier(1 for hver automat" bliver vist for ham således at han har mulighed for at bekræftige sin bestilling. Det er altså ikke den samme side der skal loades igen...
Men om jeg skriver System.Web.UI.Control ctrl=this.Page.LoadControl("sted_automat_linier.ascx"); i dopaging() eller om jeg skriver det i eventhandleren. Kommer det ikke ud på et?
siden bliver loaded på serveren når brugeren "rammer" siden - enten ved at gå ind på den - eller ved at eksekvere et postback på den ene eller den anden måde
hele kontroltræet bliver sat op for dig hver gang, og udfra kontroller, viewstate, formcontent mv. vil du efter load få eksekveret dine eventhandlers. i dit tilfælde skal handleren så samle op hvilke checkboxe der er hakket af - og viderestille til en anden siden. hvis du ikke sætter dine kontroller op hver gang - vil de simpelthen ikke eksistere når din eventhandler eksekveres. og hvis du undlader at viderestille - men bare viser siden igen, vil dine dynamisk loadede kontroller slet ikke optræde.
private void btn_Click1(object sender, EventArgs e) { Response.Write("Der er klikket på knap1"); Button btn = new Button(); btn.Text = "Button2"; btn.Click += new EventHandler(btn_Click2); Form1.Controls.Add(btn); }
private void btn_Click2(object sender, EventArgs e) { Response.Write("Der er klikket på knap2"); }
1) i page_laod sættes der en knap ind på formen, og der abbonneres på click-eventet. 2) knappen bliver vist i browseren hos klienten, og brugeern klikker på den, og eksekverer et postback. 3) på serveren sættes knappen op i kontroltræet på ny (i page_load) - og der abboneres på eventet. 4) eventhandleren eksekveres - og der indsættes endnu en knap. 5) brugeren trykker på denne nye knap og eksekverer et postback. 6) pageload køres, og den første knap sættes ind i kontroltræet.
Og mere sker der ikke her.... Knap nummer 2 bliver aldrig sat ind - da dette kun sker i eventhandleren for knap1-klikket.... og i og med at knap2 ikke bliver sat ind - kan det heller ikke udledes at der er trykket på den. knap2's eventhandler vil du derfor aldrig nogensinde kunne få kørt ved ovenstående kode.
hmm problemet er også at jeg først kan få fat i data efter de er renderet...da det jo er en nested repeater. Så jeg fylder data i repeateren efterhånden som der bliver præprocesseret.
Kan jeg på en måde få fat i repeateren efter den er blevet rendereret?
foreach(RepeaterItem ri in childRepeater.Items) { //CheckBox cb=(CheckBox)ri.FindControl("chkMakeOrder"); Response.Write(ri.GetType()+"<br>"); }
} public System.Web.UI.WebControls.Repeater getRepeater() {return childRepeater;}
#region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); }
/// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion } }
Jeg poster også lige koden for ascx filen...Så er det nemmere at se helheden :) Mange tak for din hjælp snep...Du skal nok få en ordentlig slat point hehe
selvom du så fik fat i dem der har du ikke meget at bruge dem til ... de vil ikke indeholde andet end det det bliver initialiseret med. hvis brugeren har hakket nogle af mv - vil du ikke kunne se det der.
du kan så lave dig en metode som giver dig adgang til dine checked items på samme klasse :
public ListItemCollection GetCheckedItems() { ListItemCollection checkedItems = new ListItemCollection(); foreach(ListItem li in childRepeater.Items) { CheckBox cb = (CheckBox)li.FindControl(checkboxId); if(cb.Checked) checkedItems.Add(li); return checkedItems; } }
på din side hvor du så skal bruge oplysnigerne - kan du få en reference til din brugerkontrol - og hente dine checkedItems.
dette vil du kunne gøre i en eventhandler for et knapklik på siden ell....
hvis du kan levere en enkel måde hvorpå jeg kan få projektet op at køre hos mig (f.eks. en pakket solution og en databasefil) vil jeg gerne kigge på det.
så kan du lige smide en mailadresse jeg kan skrive til.
hmmm problemet er at det kører i en oraclebase...med blandt andet et større view og sådan lidt forskelligt...Det er lidt svært at portere tror jeg...Desværre...Ville ellers have været klart det nemmeste
til tror jeg....Jeg kan stadig ikke se hvordan jeg kan skulle få fat i mit usercontrolobjekt ude i den aspx fil hvor jeg skal bruge de checked items...
Desuden skal jeg jo være sikker på at den childrepeater eksisterer når jeg kalder GetCheckedItems()...childrepeater eksisterer jo først når jeg begynder at præprocessere parentrepeateren ik? Eller har jeg misforstået?
Okay.nu tror jeg at jeg har fået noget frem her langt om længe. Jeg kan nu skrive de checkboxes ud der er valgt. Problemet er at jeg ved ikke hvilken række de kommer fra. Er der en smart måde hvorved jeg kan identificere denne checkbox?
// og en code-behind 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; using ExpArticles.ExpData;
namespace EXP2 { public class RepeaterSager : System.Web.UI.Page { protected System.Web.UI.WebControls.Repeater Repeater1; protected System.Web.UI.WebControls.Button btnGetSelectedInnerItems; protected System.Web.UI.WebControls.Repeater ChildRepeater;
du kan godt få klassen der genererer eksempeldata hvis du skulle få brug for den.
håber du kan se nogle principper i det...
du kan binde ekstra information på en given kontrol på forskellige måder, men en ganske enkel kunne være denne : someControl.Attributes.Add("SpecialAttribute", "someValue");
du kan så efterfølgende self. også hente den igen med : string someValue = someControl.Attributes["SpecialAttribute"].ToString();
(men den ryger nok ikke igennem en html-validator så ;o)
men ... når du nu alligevel har et repeateritem i hånden - kan du jo bare skrive din ekstra info i et skjult felt på dit repeateritem.... så kan du jo altid gafle det derfra igen.
men ... når du nu alligevel har et repeateritem i hånden - kan du jo bare skrive din ekstra info i et skjult felt på dit repeateritem.... så kan du jo altid gafle det derfra igen.
Hvad mener du helt præcist spørger jeg nok lidt dumt :)
Ja det kan jeg godt se det smarte i...Men problemet er at det hiddenfelt jeg skal bruge ligger inde i childrepeateren. Det er et problem da jeg får en exception når jeg prøver at binde itemboundeventet op på childrepeateren i initializeCoponent fordi den ikke er lavet endnu. Jeg får altså en nullpointerexception. Skal jeg binde eventet op et andet sted?
hej igen - jeg kom lidt senere hjem end jeg havde regnet med. hvis du bygger det op som det jeg har sendt - skulle det ikke så gerne kikse... men der kan jo altid være noget der driller. er du kommet videre med det siden du skrev 19:51 ? mvh
Hej Snep :) Jeg fik det til at virke. It aint pretty but it works hehe.....Lavede en lappeløsning....Så nu virker det da i det mindste... Det viser sig at den kun medsender de checkboxes i postback som er hakket af. Til gengæld medsender den alle hidden felter. Den bruger en navnekonvention som jeg udnyttede således at ved at fjerne ID Den laver noget ala repeater1navn1:repeater2navn1:checkboxID Så jeg kan ved at fjerne ID fra navnet og udskifte det med ID fra hiddenfeltet identificere hvilket hiddenfelt der hører til hvilken checkbox.
Som sagt det er ikke pænt...Men der er ikke så meget tid til finesser lige nu hehe. Så nu er jeg gået videre til nye problemer :) Men tusinde tak for hjælpen snepnet. Det har været meget nyttigt. DU har fortjent pointene og mange til. Smid et svar og hvis du vil have flere sig sig til. Så opretter jeg bare en ny tråd. Nå, men jeg vender nok snart tilbage :P Vi ses
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.