Tjena Hej. Det finns en del event för att komma åt dessa kontroller när de skapas och när databinds till dem. Dessa events finns i din datagrid. Inte för att vara den... men jag tog faktiskt upp detta. Dock tog jag inte upp alla event utan tog OnItemDataBound som ett ex. hehe.. jag orkade inte läsa igenom hela din post, utan tittade lite snabbt på din kod, och det såg inte ut som om du tog med eventen där :( Okej... Hittade den här koden... <code> <code> Vilken rad får du fel på? Det är panelen jag vill komma åt så att jag kan dölja den. Löste det med följande kod...trodde jagKontroller i ItemTemplate
Jag måste ha reda på hur man kommer åt kontroller som vilar inuti andra kontroller, såsom DataGrid, DataList och Repeater. Det verkar ju vara helt omöjligt att hitta kod som fungerar felfritt!
Det är så många andra som har samma problem men ingen på de forum jag har frågat har ett fungerande exempel så nu gör jag ett sista försök här på PS.
Scenariot är följande;
En panel som ligger i ett ItemTemplate på en DataGrid innehåller 2 knappar och dessa måste jag komma åt.
Kan inte förstå hur svårt det ska vara att få det här att fungera, MS borde fixa ett lättare sätt att komma åt dom här kontrollerna till nästa uppdatering.
Tacksam för svar.Sv: Kontroller i ItemTemplate
När du använder Kontroller innutti andra kontroller kommer du lätt åt dem genom att plocka alla dess kontroller.
Ex Repeater
Repeater.Controls() <-- Ger dig en ControlCollection
I denna ControllCollection ligger alla underkontroller till Repeatern.
Ex ItemTemplate i denna kan du få ut ytterliggare kontroller
i ditt fall dina knappar.
Egentligen är det inte så krångligt. Tänk dig XML där har du element du lägger sedan andra element i dessa emelemt osv. För att nå det element du vill ha får du antingen söka efter elementet, använda XPath eller gå genom en efter en för att hitta den du vill ha. Samma med kontroller förutom att du inte kan köra XPath :-)
För att söka i ex ItemTemplate kan du göra:
Du kan även söka efter controller genom metoden FrindControl(<id>)
Om vi gör det enkelt för oss så kan du typ koda:
<code>
foreach(Control x in myRepeater.Controls)
{
Button myButton = (Button)x.FindControl("<id>");
Response.Write("<font color=red>"+ myButton.UniqueID + "</font>");
}
</code>
Om du vill bläddra gör du bara en foreach i en foreach typ:
<code>
foreach(Control x in myRepeater.Controls)
{
ItemTemplate iTemplate = (ItemTemplate)x;
foreach(Control b in iTemplate.Controls)
{
Button myButton = (Button)b;
Response.Write("<font color=red>"+ myButton.UniqueID + "</font>");
}
}
</code>
Min kod var en nerbantad version. Tänk på att där Jag castar Button skulle du hantera Dina Panels. Gäller dock i Exempel två där jag går genom Hierarkier av controller, I första exemplet så går jag bara genom varje ItemTemplate och letar upp min Knapp med ID Johan.
Så här typ:
ItemTemplate.FindControl("SaveButton") letar först i din Panel som ligger under ItemTemplate har denna Panel ID SaveButton? Nej då går den in i Panelens controller och kollar finns här något med ID SaveButton? JA en knapp, så returnerar den Knappen.
Tänk nu på att du komemr få ut alla Kontroller i loopen som har ID SaveButton. Vill du ha en knapp på exakt en viss rad eller med en viss text så får du göra på lite andra sätt exempelvis kan du avända dig av Event OnItemDataBound.
Typ Web Form:
<code>
<asp:Repeater id=Repeater1 OnItemDataBound="FOO" runat="server">
</code>
CodeBehind/Scripttaggar(aspx sidan):
<code>
void Foo(Object Sender, RepeaterItemEventArgs e)
{
foreach(RepeaterItem item in e.Items)
{
...
}
}
</code>
I detta Eventet kan du ex ställa en if fråga om Button.Text är en viss text och då veta att det är den controllen du skall göra något med, kanske ändra dess text, göra den osynlig etc... Detta kan du typ även göra i de två exemplerna ovan. Denna är mer en hantering När raderna skapas, de andra har raderna redan genererats.
//Johan N
Sv: Kontroller i ItemTemplate
Du kan inte komma åt dessa kontroller innan din datagrid är skapad eftersom kontrollerna då inte finns.
Om du vill komma åt kontrollen när den skapas så finns eventet ItemCreated, vill du komma åt den när data binds till den så finns eventet ItemDataBound.
Vill du komma åt dina kontroller vid något annat tillfälle så får du göra som Johan säger. Att loppa dig igenom dem och använda dig av FindControl()
- magnusSv: Kontroller i ItemTemplate
Sedan skrev jag även:
"Denna är mer en hantering När raderna skapas, de andra har raderna redan genererats."
Fast klockan var ju runt 3 tiden så jag var lite trött kanske formulerade mig lite otydligt.
Tack för att du fyllde i med lite fler event i alla fall :-)
Take care.
//Johan NSv: Kontroller i ItemTemplate
Det vara inte alls meningen att förnimma din post. *ledsen*
- magnus Sv: Kontroller i ItemTemplate
Vart ska jag placera den här koden, jag testade att lägga den i en metod som anropades sist i Page_Load()
<code>
foreach(Control x in gbGrid.Controls)
{
ItemTemplate iTemplate = (ItemTemplate)x;
foreach(Control b in iTemplate.Controls)
{
Panel myPan = (Panel)b;
Response.Write("<font color=red>"+ myPan.UniqueID + "</font>");
}
}
</code>
och får felet att ItemTemplate inte kunde hittas.
Så jag testar med;
<code>
foreach(Control x in gbGrid.Controls)
{
Panel panel = (Panel)x.FindControl("<id>");
Response.Write("<font color=red>"+ panel.UniqueID + "</font>");
}
</code>
och får felet "Object reference not set to an instance of an object."
Och det sista exemplet OnDataItemBound visar följande fel...
'System.Web.UI.WebControls.DataGridItemEventArgs' does not contain a
definition for 'Items'
Som vanligt funkar det inte. Så nu ber jag någon att posta en komplett liten kod som hittar min panel i ett DataGrid ItemTemplate och sätter egenskapen Visible till false.Sv: Kontroller i ItemTemplate
<code>
private void CheckPanel()
{
ArrayList selectedItems = new ArrayList();
foreach ( DataGridItem repeaterItem in gbGrid.Items )
{
DataGrid itemsList = (DataGrid)repeaterItem.FindControl("pnlGBAdmin").Controls[0];
DataGridItemCollection itemCollection = itemsList.Items;
foreach ( DataListItem item in itemCollection )
{
if ( Request.QueryString["userID"].ToString() != Session["userID"].ToString())
{
Response.Write("False");
((Panel)item.FindControl("pnlGBAdmin")).Visible = false;
}
}
}
}
</code>
Fel: Specified cast is not valid. Sv: Kontroller i ItemTemplate
foreach(Control x in gbGrid.Controls)
{
Panel panel = (Panel)x.FindControl("<id>");
Response.Write("<font color=red>"+ panel.UniqueID + "</font>");
}
</code>
Detta skall fungera om du anger rätt ID och har en Panel i din Datagrid.
Hur ser din kod ut på ASPX sidan?
//Johan NSv: Kontroller i ItemTemplate
<asp:datagrid ID="gbGrid"
Width="580"
DataKeyField="ID"
OnItemCommand="GbGridItem"
ShowHeader="false"
ShowFooter="false"
BorderStyle="None"
BorderWidth="0"
AutoGenerateColumns="false"
runat="server" >
<columns>
<asp:templatecolumn>
<itemtemplate>
...
<tr>
<td colspan="2" class="regularMediumMargin"> <asp:panel ID="pnlGbAdmin" HorizontalAlign="Right" runat="server">
</asp:panel>
</tr>
</table>
</itemtemplate>
</asp:templatecolumn>
</columns>
</asp:datagrid>
</code>
<code>
foreach(Control x in gbGrid.Controls)
{
Panel panel = (Panel)x.FindControl("pnlGbAdmin");
Response.Write("<font color=red>"+ panel.UniqueID + "</font>");
}
</code>
Fel: Object reference not set to an instance of an object. Sv: Kontroller i ItemTemplate
Den hittar antagligen inte:
panel.UniqueID då den inte verkade hitta dina panels. Men var det inte knappen du skulle ha?
Vart i din codebehind utför du denna Foreach?
//Johan NSv: Kontroller i ItemTemplate
Jag kör koden i Page_Load, Det står inte på vilken rad felet uppstår.Sv: Kontroller i ItemTemplate
<code>
public void GridItemCreate(object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
if (Request.QueryString["userID"].ToString() != Session["userID"].ToString())
{
e.Item.FindControl("pnlGbAdmin").Visible = false;
}
}
}
</code>
Den påverkar endast varannan panel i datagriden...?
Löste det med:
(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)