How to get Full row from repeater control in code behind? - c#

I am using repeater control to create a table with few rows and columns. On Repeater_ItemCommand I want to select clicked row in the code behind and store it in the session. How do I do this ?
When I click the row, my e.Item.DataItem is coming NULL. I am using <%# DataBinder.Eval(Container.DataItem, "FILE_NAME")%> to bind my values in asp.net
I cant use LINQ.
Thanks
Ved

Here is the code for the repeater
<asp:Repeater ID="Repeater1" runat="server"
onitemcommand="Repeater1_ItemCommand">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:LinkButton ID="btnDeleteComment" runat="server" Text="Delete" CommandName="DeleteComment" CommandArgument=<%#Eval("myId") %>></asp:LinkButton>
<asp:Label ID="Label1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "FileName")%>'></asp:Label>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
Here is the code for the code behind
public partial class _Default : System.Web.UI.Page
{
public class myObject
{
public string FileName { get; set; }
public int myId { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
List<myObject> myList = new List<myObject>();
myList.Add(new myObject {myId = 1, FileName = "one" });
myList.Add(new myObject { myId = 2, FileName = "two" });
myList.Add(new myObject { myId = 3, FileName = "three" });
Repeater1.DataSource = myList;
Repeater1.DataBind();
}
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
Label item = (Label)e.Item.FindControl("label1");
}
}

From what i know about Repeater, it is not supposed to be used like that. Why not just use GridView and TemplateField?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="KeyColumnName"
DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField>
...Same template as in repater...
</asp:TemplateField>
</Columns>
</asp:GridView>

You can use Buttons'/LinkButtons'/etc. CommandArgument field.
<table>
<asp:Repeater ID="someRepeater" OnItemCommand="someRepeater_ItemCommand" runat="server">
<HeaderTemplate>
<tr><th>
File Name Header
</th></tr>
</HeaderTemplate>
<ItemTemplate>
<tr><td>
<asp:LinkButton Text="File Name Item" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FILE_NAME")%>' Style="display: block" runat="server" />
</td></tr>
</ItemTemplate>
</asp:Repeater>
</table>
In code behind:
protected void someRepeater_ItemCommand(object Sender, RepeaterCommandEventArgs e)
{
Session["FILE_NAME"] = e.CommandArgument; //Here you have your FILE_NAME
}
This is, of course, some example code.

Related

Repeater does not appear

the following code should show the list of websites in a repeater but it does not (though I get no errors):
In the aspx file I have:
<div>
<asp:Repeater ID="Rpt1" Visible="true" runat="server"></asp:Repeater>
<ItemTemplate>
<asp:HyperLink runat="server" Text = '<%# DataBinder.Eval(Container.GetDataItem(), "Key") %>'
NavigateUrl= '<%#DataBinder.Eval(Container.GetDataItem(), "Value") %>'>
</asp:Hyperlink>
</ItemTemplate>
</div>
In the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) return;
CaricaSiti();
}
protected void CaricaSiti()
{
ListDictionary L = new ListDictionary();
L.Add("google", #"http://google.com");
L.Add("microsoft", #"http://microsoft.com");
L.Add("yahoo", #"http://yahoo.com");
Rpt1.DataSource = L;
Rpt1.DataBind();
}
The repeater's ItemTemplate must be inside of the repeater :-)
<asp:Repeater ID="Rpt1" Visible="true" runat="server">
<ItemTemplate>
<asp:HyperLink runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Key") %>'
NavigateUrl= '<%#DataBinder.Eval(Container.DataItem, "Value") %>'>
</asp:Hyperlink>
</ItemTemplate>
</asp:Repeater>

Hide/show gridview column based on role

Want to be able to set an "Edit" linkbutton to visible=false unless the user has a role of "Editor".
Been poking around stackoverflow and elsewhere and so far have not been able to get this to work.
Gridview:
<asp:GridView ID="GridView1" runat="server" Caption="Questions Awaiting Review" AllowSorting="True" PagerSettings-Mode="NumericFirstLast"
OnPageIndexChanging="GridView1_PageIndexChanging" CaptionAlign="Top" EmptyDataText="No Questions Pending Review."
PageSize="10" AllowPaging="true" PagerStyle-HorizontalAlign="Center" PagerStyle-Font-Size="Large" DataKeyNames="QuestionID"
OnRowCommand="GridView1_RowCommand" AutoGenerateColumns="false" AlternatingRowStyle-BackColor="#cccccc"
OnPreRender="GridView1_OnPreRender">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="QuestionID" runat="server" Text='<%# Eval("QuestionID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="KeyObjective" HeaderText="Key Objective" ItemStyle-Width="250" />
<asp:BoundField DataField="SubmitDate" HeaderText="Submitted Date" ItemStyle-Width="60" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Details" CommandArgument='<%# Eval("QuestionID") %>' runat="server" CommandName="viewQuestion">View Question</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Edit" CommandArgument='<%# Eval("QuestionID") %>' runat="server" CommandName="editQuestion">Edit Question</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Have changed the code behind to use OnPreRender for the gridview, which if the value is hardcoded hides the column. However when I try to retrieve the is in role of editor then the value does not seem to be evaluating correctly. Always returns false even when the user has a role of Editor.
protected void GridView1_OnPreRender(object sender, EventArgs e)
{
if (Roles.IsUserInRole("Editor"))
{
// Enter correct column index.
GridView1.Columns[4].Visible = true;
}
else
{
GridView1.Columns[4].Visible = false;
}
}
Hoping I'm missing something simple, new to asp.net so not unlikely.
Hide last column.
this.GridView1.Columns[this.GridView1.Columns.Count - 1].Visible = Roles.IsUserInRole("Editor");
You want to show/hide an entire column instead of LinkButton control. Otherwise, unauthorized user will always see a column with blank cells which is odd.
The following example will hide an entire column.
Screen Shot (Authorize vs Unauthorized)
ASPX
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DemoWebForm.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:GridView ID="GridView1"
runat="server"
DataKeyNames="QuestionID"
OnPreRender="GridView1_OnPreRender"
AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="QuestionID" runat="server" Text='<%# Eval("QuestionID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="KeyObjective" HeaderText="Key Objective" ItemStyle-Width="250" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Edit" CommandArgument='<%# Eval("QuestionID") %>'
runat="server" CommandName="editQuestion">Edit Question</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</form>
</body>
</html>
Code Behind
public class Question
{
public int QuestionID { get; set; }
public string KeyObjective { get; set; }
}
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = new List<Question>
{
new Question {QuestionID = 1, KeyObjective = "One"},
new Question {QuestionID = 2, KeyObjective = "Two"},
new Question {QuestionID = 3, KeyObjective = "Three"},
};
GridView1.DataBind();
}
}
protected void GridView1_OnPreRender(object sender, EventArgs e)
{
bool isEditor = true; // Business logic here
if (isEditor)
{
// Enter correct column index.
GridView1.Columns[2].Visible = false;
}
}
}
Use the LinkButton like this, with the Visibility property set from a function in code behind.
<asp:LinkButton ID="Edit" Visible='<%# ShowEditBasedOnRole() %>' CommandArgument='<%# Eval("QuestionID") %>' runat="server" CommandName="editQuestion">Edit Question</asp:LinkButton>
And then in code behind the function that returns a bool
public bool ShowEditBasedOnRole()
{
if (Roles.IsUserInRole("Editor"))
{
return true;
}
else
{
return false;
}
}
One quick modification instead of accessing the column by index. it can be accessed using header text which would not affect the code even if new column is inserted before the accessed column in future the code snippet
protected void grdResults_OnPreRender(object sender, EventArgs e)
{
TemplateField FieldToAccess= grdResults.Columns.OfType<TemplateField>
().Where(f => f.HeaderText ==
"ValidityDate").FirstOrDefault();
if (role)
FieldToAccess.Visible = false;
}

How to refer to a TextBox in a datalist of the same row of the Button?

I want button in the datalist OnClick gets text from both textboxes on the same row of the button.. how can i refer to that using C# keeping in mind that I want to use my own stored procedures and functions "OnClicking" buttons without using SqlDataSource Control
<asp:DataList ID="DataList1" runat="server">
<ItemTemplate>
<table class="auto-style2">
<tr>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UDI") %>'></asp:Label>
</td>
<td>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("name") %>'></asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Eval("describtion") %>'></asp:TextBox>
</td>
<td>
<asp:Button ID="Button2" runat="server" Text="Modify" CommandArgument='<%# Eval("UDI") %>' OnCommand="Button2_Command" />
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
and here is the code behind
AdminControlEntities db = new AdminControlEntities();
var x=db.sp_GetAllProducts(); //Stored procedure that returns a selection of data
DataList1.DataSource = x.ToList();
DataList1.DataBind();
till here i get my data viewed correctly, I need to Update using my own stored procedure in this example from TextBox1 and TextBox2 to the Label1 ID
ADD OnItemCommand to your mark up
<asp:DataList ID="DataList1" runat="server" OnItemCommand="Modify_ItemCommand" >
Then on Code Behind:
protected void Modify_ItemCommand(object source, DataListCommandEventArgs e)
    {
 
        /* select the row index */
        int index = Convert.ToInt32(e.Item.ItemIndex);
 
        /*To get and Textbox of selected row*/
        TextBox txtbx = (TextBox)e.Item.FindControl("TextBox1");
 
        /* Assigning Value to your textbox */
        txtbx.Text = "What ever you want here";
 
    }
You can declare the button using the property CommandName and then use the ItemCommand event controller.
Source: http://msdn.microsoft.com/es-es/library/es4e4e0e(v=vs.100).aspx
Here, a working example (Note that I'm using an UpdatePanel. Due the content of the page is going to be change, if you do not use it you will get a server error. More info here):
Test.aspx
<asp:UpdatePanel ID="upDataList1" runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:DataList ID="DataList1" runat="server" OnItemCommand="DataList1_ItemCommand">
<ItemTemplate>
<table>
<tr>
<td>
<asp:Label ID="lUID" runat="server" Text='<%# Eval("UID") %>' />
</td>
<td>
<asp:TextBox ID="tbName" runat="server" Text='<%# Eval("name") %>' />
</td>
<td>
<asp:TextBox ID="tbDescription" runat="server" Text='<%# Eval("description") %>' />
</td>
<td>
<asp:Button ID="bModify" runat="server" Text="Modify" CommandName="Modify" />
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
</ContentTemplate>
</asp:UpdatePanel>
Test.aspx.cs
public partial class Test : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (!Page.IsPostBack) {
var x = db.sp_GetAllProducts();
DataList1.DataSource = x;
DataList1.DataBind();
}
}
protected void DataList1_ItemCommand(Object sender, DataListCommandEventArgs e) {
String a = ((TextBox) e.Item.FindControl("tbName")).Text;
String b = ((TextBox) e.Item.FindControl("tbDescription")).Text;
((Label) e.Item.FindControl("lUID")).Text = a + " " + b;
}
}
public class db {
public String UID { get; set; }
public String name { get; set; }
public String description { get; set; }
public db(String UID, String name, String description) {
this.UID = UID;
this.name = name;
this.description = description;
}
public static List<db> sp_GetAllProducts() {
List<db> list = new List<db>();
list.Add(new db("1", "1a", "1b"));
list.Add(new db("2", "2a", "2b"));
list.Add(new db("3", "3a", "3b"));
list.Add(new db("4", "4a", "4b"));
list.Add(new db("5", "5a", "5b"));
list.Add(new db("6", "6a", "6b"));
return list;
}
}

Bind a repeater dynamically inside another repeater?

I have this code:
<asp:Repeater id="repeaterCategories" runat="server">
<ItemTemplate>
<div class="categorie-item">
...
<asp:Repeater id="repeaterSubCategories" runat="server">
<ItemTemplate>
...
</ItemTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>
and repeaterSubCategories must be repeaterCategories.SubCategories, for each repeaterCategories. So I have to bind dynamically (for each first repeater iteration) a list of sub categories.
Can I do it? How?
If you have a nested repeater like this:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<asp:Repeater ID="Repeater2" runat="server"></asp:Repeater>
</ItemTemplate>
</asp:Repeater>
You can use this to bind to it:
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var data = ((MyClass)e.Item.DataItem).Subcategories;
var repeater2 = (Repeater)e.Item.FindControl("Repeater2");
repeater2.DataSource = data;
repeater2.DataBind();
}

bind data to repeater inside a gridview

Hi have a repeater which is inside a gridview. when i bind the data to gridview the data is binding to the controles inside the gridview but repeater is not binding.
<asp:GridView ID="gvMain" runat="server" AllowPaging="false" AutoGenerateColumns="false"
Width="200px" Height="200px"
onrowdatabound="gvMain_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lbtnDptName" runat="server" Text='<%# Eval("deptName")%>'></asp:LinkButton>
<asp:Label ID="lblDptDesc" runat="server" Text = "sdfsdfsdfdsf"></asp:Label>
<asp:Repeater ID="rtFunctions" runat="server" OnItemDataBound="rtFunctions_ItemDataBound" >
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="lbtnFunctions" runat="server" ></asp:LinkButton>
<asp:Label ID="lbltemp" Style="border:1px solid blue;width:20px;height:20px;background:green" runat="server" Text="TempLabel" ></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
in Page load:
gvMain.DataSource = objDeptColl;
gvMain.DataBind();
Codebehind for repeater:
protected void gvMain_RowDataBound(object sender, GridViewRowEventArgs e)
{
FunctionCollection objTempFuncColl = new FunctionCollection();
objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
Repeater rt = (Repeater)e.Row.FindControl("rtFunctions");
if (e.Row.RowType == DataControlRowType.DataRow && objTempFuncColl.Count !=0 )
{
rt.DataSource = objTempFuncColl;
rt.DataBind();
}
}
protected void rtFunctions_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
FunctionCollection objTempFuncColl = new FunctionCollection();
objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
Repeater rt = (Repeater)e.Item.FindControl("rtFunctions");
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
foreach (Functions f in objTempFuncColl)
{
LinkButton lnk = (LinkButton)e.Item.FindControl("lbtnFunctions");
lnk.Text = f.funcName;
}
}
}
linkbutton in gridview is binding but the linkbutton in repeater is not binding.
The problem appears to be with your repeater ondatabound function.
FunctionCollection objTempFuncColl = new FunctionCollection();
objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
The first line is not needed as you then replace it with the contents of the cache, which might be null if it's expired or purged or an instance.
For each row in your repeater, the link will be set to the last value in the objtempfunccoll.
you don't really need any of the function apart from lnk.Text = f.funcName; (you'll need to cast f from dataitem)
When you databind to the gridview, ondatabound is called for each row. you've got that wired-up. For each row you now need to find the repeater, set its datasource (we'll call this inner collection) & call databind on the repeater. this will cause ondatabound on the repeater to be called but the container.dataitem now points to each item in the inner collection. We can use that directly, casting container.dataitem to whatever type the inner collection is a list of.
protected void gvMain_RowDataBound(object sender, GridViewRowEventArgs e)
{
FunctionCollection objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
Repeater rt = (Repeater)e.Row.FindControl("rtFunctions");
if (e.Row.RowType == DataControlRowType.DataRow && objTempFuncColl.Count !=0 )
{
rt.DataSource = objTempFuncColl;
rt.DataBind();
}
}
protected void rtFunctions_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
lnk.Text = ((Functions)e.Item.DataItem).funcName;
}
Simon
You do not appear to be binding the repeater within any of this code. You may have some code to bind data to the GridView control, but this will not automatically bind anything to the repeater within the ItemTemplate.
Why don't databind in the aspx, leaving empty the code behind:
<asp:GridView ID="gvMain" runat="server" AllowPaging="false" AutoGenerateColumns="false"
Width="200px" Height="200px">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lbtnDptName" runat="server" Text='<%# Eval("deptName")%>'></asp:LinkButton>
<asp:Label ID="lblDptDesc" runat="server" Text = "sdfsdfsdfdsf"></asp:Label>
<asp:Repeater ID="rtFunctions" runat="server" DataSource='<%# Cache["objFuncColl"] %>' >
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="lbtnFunctions" runat="server" Text='<%# Eval("funcName") %>' ></asp:LinkButton>
<asp:Label ID="lbltemp" Style="border:1px solid blue;width:20px;height:20px;background:green" runat="server" Text="TempLabel" ></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Categories

Resources