Get data being bound to ListView on DataBound event - asp.net

I have a ListView control and I have added a DataBound event (don't know if this is the correct one) to the control.
I'm wanting to access the data being bound to that particular ItemTemplate from this event, is that possible?

C# Solution
protected void listView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
// you would use your actual data item type here, not "object"
object o = (object)dataItem.DataItem;
}
}
Why they made this so different for ListView still sort of puzzles me. There must be a reason though.

A little late, but I'll try to answer your question, as I had the same problem and found a solution. You have to cast Item property of the ListViewItemEventArgs to a ListViewDataItem, and then you can access the DataItem property of that object, like this:
Private Sub listView_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles productsList.ItemDataBound
If e.Item.ItemType = ListViewItemType.DataItem Then
Dim dataItem As Object = DirectCast(e.Item, ListViewDataItem).DataItem
...
End Sub
You could then cast the dataItem object to whatever type your bound object was. This is different from how other databound controls like the repeater work, where the DataItem is a property on the event args for the DataBound method.

Found a workaround, I created a method to format the data how I needed and called it from the markup using:
<%# doFormatting(Convert.ToInt32(Eval("Points")))%>

The data that is used for the current item can be found from the EventArgs.
So from the RepeaterItemEventArgs e we can access the current item by looking in e.Item.DataItem.
protected void listView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var currentItem = e.Item.DataItem;
}
}

Related

Use AsyncFileUpload in a grid view in update panel

I want to use a AsyncFileUpload in a grid view and each record must have a AsyncFileUpload individually. In addition user must be able to upload his/her file for each record.
Now how can i access AsyncFileUpload in the grid view and check it if it has a file or not?
For common file upload i have used the below cod:
((FileUpload)GridView1.Rows[idx].Cells[0].FindControl("FileUpload1") as FileUpload).HasFile
However, it is not acceptable in this situation.
Is there any way to access this Ajax controller in a grid view?
on your asyncfileupload bind OnUploadedComplete event to the method
OnUploadedComplete = "FileUploded"
code:
protected Sub FileUploded(object sender, EventArgs e)
Dim fu AjaxControlToolkit.AsyncFileUpload
Dim row As GridViewRow = CType(fu.NamingContainer, GridViewRow)
Dim idx = row.RowIndex
fu = ctype(sender,AjaxControlToolkit.AsyncFileUpload)
If fu.HasFile then
--do something--
End If
End Sub
c#:
protected void FileUploded(object sender, EventArgs e)
{
AsyncFileUpload fu = (AjaxControlToolkit.AsyncFileUpload)sender;
GridViewRow row = (GridViewRow)fu.NamingContainer;
string idx = row.RowIndex.toString();
}

Getting Position of Sender Control in Gridview Template Field

I have a dropdownlist control in a datagrid template field. In the SelectedIndexChanged event, I just want to get the position of the sender object in order to create a reference to the row the sender object was in. All I've found on google is how to loop through each row of the datagrid to compare it to sender's client ID to see if it is in fact my selected row. Why can't I just get the position of the sender object and just use it to create an instance of that gridviewrow? And why doesn't the below work?
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = (GridViewRow)GridView1.SelectedRow;
var store = row.Cells[0].Text; //I get the Object reference not set to an instance of an object error here
}
Am I missing something?
The sender is the DropDownList. Its NamingContainer is the GridViewRow. This has a property RowIndex. I assume that this (or the row) is what you want. Here is both:
var row = (GridViewRow)((Control)sender).NamingContainer;
var rowIndex = row.RowIndex;

Find a Control inside ASP:Repeater

I am trying to access a control inside a Repeater. The control is inside the <ItemTemplate> tag. I am using FindControl but it's always coming out Null.
What am I doing wrong?
My guess is that FindControl can only be used in record-level events such as ItemDataBound:
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
(ControlTypeCast) e.Item.FindControl("myControl")).SomeProperty = "foo";
}
I'm guessing that you're trying to find a control at the wrong point in the page lifecycle. The ItemDataBound event is where you need to look for it.
This example is in vb.net, but I'm sure you get the idea.
Protected Sub rp_items_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rp_items.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim someLiteral As Literal = e.Item.FindControl("someliteral")
End If
End Sub
In most cases, spelling the control name wrong :) It may also be that you are searching for a control that exists within another container. Can you post your code?
for (int i = 0; i <= repeater1.Items.Count - 1; i++)
{
Button delete = (Button)repeater1.Items[i].FindControl("btnDelete");
delete.Visible = true;
Button edit = (Button)repeater1.Items[i].FindControl("btnEdit");
edit.Visible = true;
}
Vb.net
For i As Integer = 0 To Repeater1.Items.Count - 1
Dim CmbTyp As DropDownList = DirectCast(Repeater1.Items(i).FindControl("DropDownList1"),DropDownList)
Dim SeatN As Label = DirectCast(Repeater1.Items(i).FindControl("label1"), Label)
styp = CmbTyp.SelectedItem.Text.Trim
sNo = SeatN.Text
Next
Try This
For vb.net
CType(e.Item.FindControl("myControl"), Literal).Text = "foo"
For c#
[Literal]e.item.FindControl["myControl"].Text="foo";

Accessing the full DataRow from the DataSource in a ListView ItemDataBound event handler

Is it at all possible within a ListView ItemDataBound event handler to gain access to the full DataRow for that event? I need to do a lot of processing for the entire row on binding, but using data item values in the datarow that I am not actually using in the display itself.
Try this
DataRowView dr = (DataRowView)DataBinder.GetDataItem(e.Item);
using
dr.Item.ItemArray you can access the entire row.
Perhaps try to use the ListViewDataItem property to access the properties of the underlying data object to which the object is bound. The ListViewDataItem property is only available during and after the ItemDataBound events of the control and usually corresponds to a record in your data source object.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listviewdataitem.aspx
Below is an example.
protected void listProducts_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
string prodtype = (string)DataBinder.Eval(dataItem, "ProductType");
// ...
}
}

how to raise event from dynamically created usercontrol

How do I raise an event from a user control that was created dynamically?
Here's the code that I'm trying where Bind is a public EventHandler
protected indDemographics IndDemographics;
protected UserControl uc;
override protected void OnInit(EventArgs e)
{
uc = (UserControl)LoadControl("indDemographics.ascx");
IndDemographics.Bind += new EventHandler(test_handler);
base.OnInit(e);
}
I get a null object for IndDemographics. Can anyone point me to a complete code sample?
Thanks in advance...
First off, you'll need to make sure that you have the event defined in your usercontrol's code.
for example:
public class MyUserControl
Inherits UserControl
Public Event Bind(sender as object, e as EventArgs)
public sub SomeFunction()
RaiseEvent Bind(me, new EventArgS())
End Sub
End Class
After this, then you can bind to the Event. Now,for your other issue, are you loading this control dynamically or is it declared on your ASPX side? If it's on your ASPX side, then you don't need the LoadControl, as declaring an object as Runat=Server on the ASPX side instantiates an instance of said class.
If not, then you'll need to make sure you're using the Virtual Path for the location of the ASCX file. (in your example, you'd use "~/indDemographics.ascx" if the ASCX was at the root of the website). At this point you'd need to add it to the page (or a placeholder or some other container object).
Regardless, of which way you instantiate an instance of the UserControl, you then associate the Event Handler to the Event of the instance of the class. For example:
Dim btn As New Button;
AddHandler btn.Click, AddressOf MyButtonClickEventHandler
Now, for the reason that you're getting a NULL reference in the example code.
When you use the LoadControl reference, then the instance of your object is in the UC variable. In the example, you declare two objects, UC as a type of UserControl and indDemographics as a type of indDemographics.
When you use the LoadControl, you're instantiating an instance of indDemographics and assigning it to UC. When you try to assign the event handler to the IndDemographics variable, it has never actually been instantiated.
Ultimately, your code should look more along these lines:
protected indDemographics IndDemographics;
override protected void OnInit(EventArgs e)
{
indDemographics = LoadControl("~/indDemographics.ascx");
IndDemographics.Bind += new EventHandler(test_handler);
base.OnInit(e);
}
I see it (IndDemographics) declared but never actually created, so I'd expect it to be null with just this code.
Thanks to Stephen for getting me on the right track. Here's the final working code in C#:
protected indDemographics IndDemo;
override protected void OnInit(EventArgs e)
{
Control c = LoadControl("~/indDemographics.ascx");
IndDemo = (indDemographics) c;
IndDemo.Bind += new EventHandler(test_handler);
place1.Controls.Add(IndDemo);
base.OnInit(e);
}
It's important to cast the generic control into the indDemographics class. After that everything else works fine.

Resources