Findcontrol in listview itemtemplate - asp.net

I have the next code in itemtemplate:
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<asp:HiddenField Value='<%# checkCatName(Eval("CatName")) %>' runat="server" />
........
<asp:Label runat="server" id="lblBla" Visible="false"> ... </asp:Label>
</ItemTemplate>
</asp:ListView>
Code Behind (C#):
public void checkCatName(object CatName)
{
Label bla = (Label)ListView1.FindControl("lblBla");
if (CatName.ToString() == "test1")
bla.Visible = true;
return CatName.ToString();
}
I get null - like the page dont find the "bla" label.
Where i'm wrong ?

to get item which is in the listview or a repeater, you will need to go through items in this view and then find control (hidden field).
Page will not be able to find that control directly.
Hope that helps.

If the listview has an itemdatabound event you can use it to find the control and do what ever you need with it. The following code is assuming you have a hidden field in your listview item template with the id="myhiddenfield"
//this goes inside your listview's itemdatabound event
HiddenField myhiddenfield = new HiddenField();
myhiddenfield = (HiddenField)e.Item.FindControl("myhiddenfield");
//get or set hidden field value here.
int myID = Convert.ToInt32(myhiddenfield.Value);

Related

Passing CommandArguement to LinkButton from variable

I have seen many resources on SO that say that I can use following syntax to pass value to CommandArguement of `LinkButton'
<%forearch(var comment in Comments){%>
<asp:LinkButton ID="del" CommandArguement='<%= comment.CommentId%>' onCommand="delete_click" Text="Delete"/>
<%}%>
But when I write this in my ascx file and click on the link the value passed to command argument is "<%=comment.CommentId%>" instead of commentId itself. Please guide what am I doing wrong?
Edit 1
based on answers and comments, I have moved to use repeater instead of foreach and plain code. Here is the code I have come up with
<asp:Repeater ID="commRepeater" SelectMethod="GetPageComments" runat="server">
<ItemTemplate>
<p>
<%#Eval("Comment") %>
<%if(Page.User.Identity.IsAuthenticated && Page.User.Identity.GetUserId() == Eval("UserId")){ %>
<span>
<asp:LinkButton Text="Edit" runat="server" ID="EditLink" CommandArgument='<%#Eval("CommentId")%>' OnClick="Update_Comment" />
<asp:LinkButton Text="Delete" runat="server" ID="DeleteLink" CommandArgument='<%#Eval("CommentId")%>' OnClientClick="if (!confirm('Are you sure you want delete?')) return false;" OnCommand="Delete_Comment" />
</span>
<%} %>
</p>
</ItemTemplate> </asp:Repeater>
you can see that I am trying to show the edit and delete links if user is logged in and his Id matches with user who commented but it tells me that I can on use Eval in databound controls. how would I hide/show edit/delete links conditionally within repeater
You could simply use codebehind, for example in Page_Load:
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
del.CommandArgument = comment.CommentId;
}
}
Maybe a better approach would be to use the Comments-collection(which seems to be a list or array of a custom class) as DataSource of a Repeater(or other web-databound control). Then you can add the LinkButtons to the Itemtemplate.
You can then either use ItemCreated or ItemDataBound events of the repeater in codebehind or inline ASP.NET tags to bind the CommandArgument.
For example:
CommandArguement='<%# DataBinder.Eval( Container.DataItem, "CommentId" ) %>'
What you are doing currently is not recommended and is highly error prone. You can easily achieve this with ASP.NET Repeater control like this:-
<asp:Repeater ID="MyRepeater" runat="server">
<ItemTemplate>
<asp:LinkButton ID="del" CommandArguement='<%# Eval("CommentId") %>'
OnCommand="del_Command" Text="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
In Page_Load simply bind it:-
if (!Page.IsPostBack)
{
MyRepeater.DataSource = CommentsRepository();
MyRepeater.DataBind();
}
Or Else if you are have ASP.NET 4.5 then use strongly type Data Bound controls like this:-
<asp:Repeater ID="MyRepeater" runat="server" ItemType="MyNamespace.Comment"
SelectMethod="MyRepeater_GetData">
<ItemTemplate>
<asp:LinkButton ID="del" CommandArguement='<%# Item.CommentId %>'
OnCommand="del_Command" Text="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
And you method in code behind should be something like this(just for Demo):-
public IEnumerable<MyNamespace.Comment> MyRepeater_GetData()
{
return new List<Comment>
{
new Comment { CommentId =1, Name= "foo"},
new Comment { CommentId =2, Name= "bar"},
};
}

Event not firing as expected for control in formview asp.net

I have a LinkButton in an InsertItemTemplate which when clicked, should display a hidden DropDownList in the InsertItemTemplate. However, it doesn't seem to be working, but it will say, change the text of a label outside the Formview when the LinkButton is clicked. The event is firing, but the part to make the DropDownList visible in the InsertItemTemplate is not doing anything. Code is below:
.aspx:
<asp:FormView ID="formViewNewRecord" runat="server">
<InsertItemTemplate>
<asp:DropDownList ID="ddlAddSelection2" runat="server" DataSourceID="dSource1" DataTextField="Users" DataValueField="Users" AppendDataBoundItems="true" Visible="false">
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
<asp:LinkButton runat="server" ID="lbAddAnother" OnClick="lbAddAnother_Click">+Add Another</asp:LinkButton>
</InsertItemTemplate>
</asp:FormView>
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
C#:
protected void lbAddAnother_Click(object sender, EventArgs e)
{
DropDownList addSelection2 = (DropDownList)formViewNewItem.Row.Cells[0].FindControl("ddlAddSelection2");
addSelection2.Visible = true;
Label2.Text = addSelection2.ID;
}
Your dropdown control is not an immediate child of your formview. So since the FindControl call is not recursive, you have to search for the control in the right location of your form view's child controls. See this for the details but at a high level, you need something along the lines of:
DropDownList ctrl = (DropDownList)FormView1.Row.Cells[0].FindControl("ddlAddSelection2");
After that, you should check it for null for safe measure.

Using hyperlink with querystring for gridview row

Is there someway to turn the row of a gridview into a hyperlink so that when a user opens it in a new tab for example, it goes to that link? Right now I am using a LinkButton and when the user opens it in a new tab, it doesn't know where to go.
I figured the .aspx code would look something like:
<asp:TemplateField>
<ItemTemplate>
<Hyperlink ID="hyperlink" runat="server" ForeColor="red" HtmlEncode="false" navigationURL="testUrl.aspx"
</ItemTemplate>
</asp:TemplateField>
The only thing is, our URLs are set up in the C# code behind as a query string, so I'm not sure how to pass that into the navigationURL section.
I'm guessing there's something I can do on the page_load with the query string to redirect to the page I need, but this is my first time working with query strings so I'm a little confused.
Thanks!
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#String.Format("~/controller.aspx?routeID1={0}&routeID2={1}", Eval("routeid1"), Eval("routeid2"))%>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
routeid1 and routeid2 are passed as query strings to the controller of that page.
What I did recently is modified my class to have a readonly property that constructs the A tag for me. This way I have control over what gets displayed; just text or a link.
<ItemTemplate>
<asp:Label ID="ColumnItem_Title" runat="server" Text='<%# Bind("DownloadATag") %>'> </asp:Label>
</ItemTemplate>
The code behind just binds an instance of the class to the gridview. You can bind the gridview whenever, on load on postback event, etc.
Dim docs As DocViewList = GetViewList()
GridViewDocuments.DataSource = docs
GridViewDocuments.DataBind()
In the above code, the DocViewList, instantiated as docs, is a list of a class that has all the properties that are needed to fill my GridView, which is named GridViewDocuments here. Once you set the DataSource of your GridView, you can bind any of the source's properties to an item.
Something like:
<asp:LinkButton ID="LinkButton_Title" runat="server" target="_blank"
PostBackUrl='<%# Eval(Request.QueryString["title"]) %>'
or binding them from the RowCreated event:
protected void GridView_OnRowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
(e.Row.FindControl("LinkButton_Title") as LinkButton).PostBackUrl = Request.QueryString["title"]))
}
}

ASP.NET: Bind a value to a custom user control inside a repeater

I have an ASP.NET control that binds data to a repeater. Inside that repeater, I have another custom user control. I want to pass a value to this second control based on the current binding item.
<asp:Repeater runat="server" ID="ProductList">
<ItemTemplate>
<p>Product ID: <%# Eval("ProductID") %></p>
<myControl:MyCoolUserControl runat="server" ProductID='<%# Eval("ProductID") %>' />
</ItemTemplate>
</asp:Repeater>
The repeater item template correctly prints out my Product ID with the Eval statement, but when I do the same thing to pass the Product ID to MyCoolUserControl, it doesn't work (if ProductID on MyCoolUserControl is a Nullable Int32 - I can debug it and it's always null).
Any ideas how I can do this?
I did a small test and I got it working if the ProductID is a string. After I changed it to and int in the usercontrol I got kind of the same problems.
I did a int.Parse in the datasource to the repeater and got it working again.
Check to see that the ProductId that you pass into the repeaters datasource is of type int.
Mytest app.
string[] values = new string[]{ "12", "13" };
MyRepeater.DataSource = from v in values
select new
{
ProdId = int.Parse(v)
};
MyRepeater.DataBind();
<asp:Repeater runat="server" ID="MyRepeater">
<ItemTemplate>
<My:control runat="server" ProductId='<%# Eval("ProdId") %>' />
</ItemTemplate>
</asp:Repeater>
and in the usercontrol:
public int? ProductId
{
set { MyLabel.Text = value.Value.ToString(); }
}

Use data in repeater when Checkbox is check in ASP.net

I have a repeater for showing my data . this repeater showing 2 field that one of feild is checkBox Control and other is a lable.
NOW , how can I understand text of lable when the checkBox is Checked?
I want to see text of lable in evry row that the CheckBoxes is checksd.
how do I do?
I use LINQtoSQL for get and set data from database
On postback, you need to loop through every row of your repeater, and grab out the checkbox control. Then you can access it's .Checked and .Text properties. If it's .Checked, then add it to a list or array. I can elaborate if needed..
Page...
<asp:CheckBox ID="chkBoxID" runat="server" OnCommand="doSomething_Checked" CommandArgument="<%# Some Binding Information%>"
CommandName="NameForArgument">
</asp:CheckBox>
Code Behind...
protected void doSomething_Checked(object sender, CommandEventArgs e) {
CheckBox ctrl = (CheckBox)sender;
RepeaterItem rpItem = ctrl.NamingContainer as RepeaterItem;
if (rpItem != null) {
CheckBox chkBox = (LinkButton)rpItem.FindControl("chkBoxID");
chkBox.DoSomethingHere...
}
}
<asp:Repeater ID="rptX" runat="server">
<ItemTemplate>
<asp:Label ID="lblX" runat="server" Visible='<%# Eval("IsChecked") %>' />
<asp:CheckBox ID="chkX" runat="server" Checked='<%# Eval("IsChecked") %>' />
</ItemTemplate>
</asp:Repeater>
And code behind when you assign your data
rptX.DataSource = SomeIEnumerableFromLinq; // which has a bool field called IsChecked
rptX.DataBind();

Resources