Hej, Testa: Hej Pelle, Hej Magnus Hej Björn, Hej Magnus Hej Björn,Hur sätta/hitta id på CHECKBOX i Repeater?
jag har ett fromulär med en repeater som för varje post i DataSourcens Dataset skapar en <ASP: CHECKBOX>. Jag vill matcha mot ett värde i ett annat dataset för att avgöra om den skall vara Checked eller inte. Men det går inte att ange id för en <ASP: CHECKBOX> inuti en repeater. text går att ange så kanske kan jag få tag på den på det viset.
Jag testade enligt nedan men får ingen ordning på det, hur skall jag göra för att få tag på min checkbox när jag inte kan ge de ngt id?
<CODE>
private void repeaterSite_ItemCreated(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
CheckBox chk = (CheckBox)e.Item.Controls[0];
// Lite kod för att kolla om den skall vara Checked.
}
</CODE>
/MagnusSv: Hur sätta/hitta id på CHECKBOX i Repeater?
for(int cnt = 0; cnt < urRepeater.Items.Count; cnt++)
{
// your checkbox ; type casting
CheckBox cbId = ((CheckBox) urRepeater.Items[cnt].FindControl("cbId"));
// user id
int id = Convert.ToInt32(cbId.ToolTip);
// or the other option; value from hidden field
if (cbId.Checked)
{
// Your code
}
}
Och lägg till detta till repeatern:
<# DataBinder.Eval(Container.DataItem,"ur_Id")%>
Sv:Hur sätta/hitta id på CHECKBOX i Repeater?
jag skall nog beskriva hela problembilden (om du orkar läsa hela...). Kanske finns bättre sätt att lösa hela problemet.
Mitt formulär används för att skapa en ny post eller för att editera en befintlig post. Förutom att fylla i ett antal textfält skall man välja en eller flera städer. I min repeater läser jag upp ett antal städer (antalet kan variera) från en databastabell, för varje stad vill jag skapa en checkbox med samma id som staden har i databasen och dessutom bredvid checkboxen skriva ut namnet på staden.
När man skapar en post kryssar man i en eller flera städer, när användaren klickar på Save-knappen behöver jag sedan veta id för alla de städer där användaren har kryssat i checkboxen. Dessa id lagrar jag sedan i ett Dataset tillsammans med övrig info som jag via ett Facade Layer skickar till mitt Data Access Layer som kommunicerar med databasen. För varje stad/checkbox som var ikryssad skapas en post i en relationstabell.
När jag sedan vill editera den skapade posten så vill jag kolla vilka id(på städer) som finns i databasen och utifrån dessa avgöra vilka som skall vara ikryssade när posten visas. Jag har provat 2 olika lösningar men stupat på båda:
1. <ASP:CHECKBOX> Problemet är att jag inne i en Repeater inte kan ge varje <ASP:CHECKBOX> ett id utan de får ngt konstigt id kopplat till repeatern, därför kan jag inte heller jämföra med värdena från databasen för att avgöra om checkboxen skall vara ikryssad eller ej
2. Vanlig HTML checkbox. Funkar bra att ge checkboxarna samma id som posten har i databasen. Problemen uppstår när jag vill visa och editera en redan skapad post. Jag vet ju från databasen vilka checkboxar som skall vara ikryssade men jag får inte tag i dem. I min codebehind skriver jag typ:
<CODE>
CheckBox chk = new CheckBox();
chk = (CheckBox)frmPerson.FindControl(drPerson_To_City.city_id.ToString());
chk.Checked = true;
</CODE>
Checkboxen har ju samma id som staden har i databasen.
Problemet verkar vara att eftersom det är en HTML-kontroll så hittas aldrig kontrollen, dvs chk är undefined och så går det som det går.
Av användbarhets- och designskäl vill jag använda checkboxar men går det inte så får jag använda ngt annat.
Ngn idé?
/MagnusSv: Hur sätta/hitta id på CHECKBOX i Repeater?
Jag antar att du använder en DataTable som du binder mot Repeatern.
Ifall du med SQL-queryn skulle kunna få med en kolumn som beskrev ifall staden skulle vara vald eller inte så kan du skriva följande i din Repeater-deklarering:
<code>
<ItemTemplate>
<tr>
<td>
<asp:CheckBox Runat="server" Text=<%# DataBinder.Eval(Container.DataItem, "Namn")%> Checked=<%# DataBinder.Eval(Container.DataItem, "Selected")%> ></asp:CheckBox>
</td>
</tr>
</ItemTemplate>
</code>
Ifall det inte fungerar, och du vill använda ItemCreated-eventet så skulle du kunna göra så här:
// Se till att det är protected istället för private
protected void repeaterSite_ItemCreated(object sender, RepeaterItemEventArgs e) {
// Ignorera Header, Footer etc
if ( e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem ) {
// Iterera alla controls för att hitta just checkboxen
// Detta skulle kunna fixas med e.Item.FindControl("checkboxid") också
for ( int i = 0 ; i < e.Item.Controls.Count ; i++ ) {
// 'as' returnerar null ifall det inte är en CheckBox istället för att kasta exception
CheckBox chk = e.Item.Controls[i] as CheckBox;
if ( chk != null ) {
// Se till att alla städer som innehåller 'ö' blir valda
chk.Checked = (((DataRow) e.Item.DataItem)["Stad"].ToString().IndexOf("ö") != -1);
}
}
}
}
Andra sätt att göra det på skulle kanske kunna vara att anväda en CheckBoxList, eller att du efter din MyRepeater.DataBind();, loopa igenom Repeatern.
Du skulle också kunna generera dina CheckBox:ar själv, utan att använda dig av en repeater.
Hoppas det hjälper
// MvH Björne
Sv:Hur sätta/hitta id på CHECKBOX i Repeater?
jag provade inte dina exempel men de fick mig att tänka lite annorlunda och jag lyckades lösa det! Tack för hjälpen!
Jag låter repeatern skapa mina <ASP:CHECKBOX> och ger attributet NAME värdet av namnet på staden. Efter att användaren klickat Save kör jag följande kod:
<CODE>
// För varje repeaterItem i min repeater
foreach(RepeaterItem rpt in frmPerson.repeaterCity.Items)
{
// För varje kontroll i ett repeaterItem
foreach(Control ctrl in rpt.Controls)
{
// Om det är en checkbox
if(ctrl.GetType().FullName == "System.Web.UI.WebControls.CheckBox")
{
CheckBox chk = (CheckBox)ctrl;
// Om den är ikryssad
if(chk.Checked)
{
// Använd textattributet för att leta upp posten i City DataTable
drCity = (TdsCity.CityRow)(tdsCity.City.Select("city_name = '" + chk.Text + "'")[0]);
// Lite kod för att skapa en post i databasen
// drCity innehåller bl a city_id som jag behöver spara ner tillsammans med ett person-id
}
}
}
</CODE>
Liknande kodning kan jag sedan använda för att läsa upp en befintlig person post och kryssa i de valda städerna, m h a drCity.city_name kan jag loopa igenom textboxarna och matcha mot textattributet tills jag hittar rätt och då kryssa i checkboxen.
Känns inte som en klockren lösning, det är hyfsat bökigt men det fungerar i alla fall.
Ngn som vet varför det inte är möjligt att tilldela en CheckBox ett id inne i en repeater? Det var ju det som ställde till med problem för mig. Varför har Microsoft valt att sätta denna begränsning?
/MagnusSv: Hur sätta/hitta id på CHECKBOX i Repeater?
Jag kan inte säga att det är så, men jag skulle tippa på att anledningen till att man inte kan sätta ID:t i en repeater är för att Repeatern måste se till att ID:na är unika iom att den skapar flera stycken, och att den inte tycker om att den inte får bestämma det själv.
En annan liten grej som jag ville nämna är att jag inte är så förtjust i att jämföra med text-strängar ifall man inte måste, eftersom man inte får någon syntax-checking på strängen.
Du kan skriva om if-satsen så här:
foreach(RepeaterItem rpt in frmPerson.repeaterCity.Items) {
foreach(Control ctrl in rpt.Controls) {
if(ctrl is CheckBox) {
CheckBox chk = (CheckBox)ctrl;
if(chk.Checked) {
drCity = (TdsCity.CityRow)(tdsCity.City.Select("city_name = '" + chk.Text + "'")[0]);
// Lite kod för att skapa en post i databasen
}
}
}
}
Också ett alternativ:
foreach(RepeaterItem rpt in frmPerson.repeaterCity.Items) {
foreach(Control ctrl in rpt.Controls) {
CheckBox chk = ctrl as CheckBox;
if(chk != null && chk.Checked) {
drCity = (TdsCity.CityRow)(tdsCity.City.Select("city_name = '" + chk.Text + "'")[0]);
// Lite kod för att skapa en post i databasen
}
}
}
}
// MvH Björne
Sv:Hur sätta/hitta id på CHECKBOX i Repeater?
jag plockar med mig <CODE> if(ctrl is CheckBox) </CODE>, klart snyggare än min <CODE> GetType().FullName </CODE>.
/Magnus