how bind DataList template field in asp.net - asp.net

i want to bind a label -i created- in Datalist template to col -named "item"-in my dataSource
i used the following code after several trials
DataList2.DataSource = dt; // my DataSource
Label l1 = (Label)DataList2.FindControl("itemLabel");
l1.Text = dt.Rows[0]["item"].ToString();
DataList2.DataBind();
i got the following error at line '3' i am looking for the right expression
Object reference not set to an instance of an object.
any help would be appreciated..

The label is null since it's NamingConainer(used for FindControl) is not the DataList but one of it's DataListItems (a DataList is used for multiple items).
So you need to DataBind it first, then you can handle it's ItemDataBound event. There you are able to find the label and the underlying DataItem.
void Item_Bound(Object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
// Retrieve the Label control in the current DataListItem.
Label itemLabel= (Label)e.Item.FindControl("itemLabel");
DataRow row = ((DataRowView)e.Item.DataItem).Row;
String item = row.Field<string>("item");
itemLabel.Text = item;
}
}

Related

Why would formview disappear in Edit Mode

I know I must be missing something simple but I cannot find it so I will pose the question here. I have a formview with two templates (item and edititem).
The form is bound to the itemtemplate in the page_Load event and works fine. However, if is use !IsPostBack in the code-behind, the formview disappears when the edit button is clicked. If I remove the postback check from page_load, then the form view appears after the edit button is clicked.
The page does have viewstate enabled.
In general, what steps are needed to get the formview to transition between modes correctly?
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
source = Session["Source"].ToString();
acctType = Session["AccountType"].ToString();
acctNumber = Convert.ToInt32(Session["AccountNumber"]);
if (source == "LifeLineDS")
{
ObjectDataSource fvObjDS = new ObjectDataSource();
fvObjDS.TypeName = "LifelineDataAccess.LifelineSubscriber";
fvObjDS.SelectMethod = "GetLifelineDSSubscriber";
fvObjDS.SelectParameters.Add(new Parameter("AcctType", TypeCode.String, acctType));
fvObjDS.SelectParameters.Add(new Parameter("AcctNumber", TypeCode.String, Session["AccountNumber"].ToString()));
fvObjDS.DataBind();
if (fvObjDS != null)
{
fvSubscriber.DataSource = fvObjDS; //subscriber.ToString();
fvSubscriber.DataBind();
initialProgramValue = (fvSubscriber.FindControl("txtEligibility") as TextBox).Text;
}
}
// more code for other sources...
}
protected void btnEdit_Click(object sender, EventArgs e)
{
fvSubscriber.ChangeMode(FormViewMode.Edit);
fvSubscriber.DataSource = Session["subscriber"]; //Adding this line resolved !IsPostBack problem
fvSubscriber.DataBind();
ObjectDataSource programsObjDS = new ObjectDataSource();
programsObjDS.TypeName = "LifelineDataAccess.LifelineSubscriber";
programsObjDS.SelectMethod = "GetPrograms";
DropDownList ddlEligibility = ((DropDownList)(fvSubscriber.FindControl("ddlEligibility")));
if (ddlEligibility != null)
{
ddlEligibility.DataSource = programsObjDS;
ddlEligibility.DataTextField = "ProgramName";
ddlEligibility.DataValueField = "ProgramName";
ddlEligibility.SelectedValue = initialProgramValue; // Set selected value to subscribers current program
ddlEligibility.DataBind();
}
}
This
fvSubscriber.ChangeMode(FormViewMode.Edit);
fvSubscriber.DataBind();
seems to not to set the data source. The rule is that either you have the DataSourceID set in the declarative part of your code (*.aspx, *.ascx) and the binding is done automatically upon each postback OR you bind programmatically which involves setting the data source and calling the DataBind().
My recommendation would be to move your ObjectDataSource to the declarative part of the code and set the DataSourceID on the FormView to the ID of the ObjectDataSource. This is clean and easy and the binding works always.

Equivalent of Eval("field") in ASP.NET Repeater ItemDataBound event?

I want to do the equivalent of Eval("field") in an ASP.NET repeater ItemDataBound Event but am not sure what to cast e.Item.DataItem as. The data source type could vary as this is reusable code in a custom control. So how can I access a field in e.Item.DataItem by field name (a string)?
Ideally I want to do something like:
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
xxx item = (xxx)e.Item.DataItem;
string fieldValue = item("fieldname");
}
}
If you don't know what the type is at compile time your only option is to treat is as an object (which is the default return type for the DataItem property).
You could try using:
object item = DataBinder.Eval(e.Item.DataItem, "fieldname");
You're still stuck with an object at the end of that call, but (assuming the call is successful) you'll know that item has a property named fieldname. I don't know if that helps. Perhaps update your question with more detail about what you're trying to do.
instead of xxx item = (xxx)e.Item.DataItem;
write it:
var item = e.Item.DataItem;
or may be:
object item = e.Item.DataItem;

Getting a column name in a Repeater in OnItemCreated

I am working on a Repeater that reads from a table with a layout something like:
string Title
string Location
bool Water
bool Sewer
bool Picnic_Table
bool On_Beach
...
I am creating a list of amenities for each "Title" so I need to loop through the columns and get a list of amenities for each Title (or site). Optimally, I have a loop to go through the list. Something like
for each column
if column is not Title or Location
Append to StringBuilder "column name"
How do I get that column name to do the comparisons?
Here's how to get the column name in the OnItemCreated event of the Repeater control:
protected void rptOnItemCreated_OnItemCreated(object sender, RepeaterItemEventArgs e)
{
string columnName = string.Empty;
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
DataRow dr = drv.Row;
foreach (DataColumn dc in dr.Table.Columns)
{
// Do what you want with the column name
columnName = dc.ColumnName;
}
}
}
Repeater is not a table-based control, so that's going to be hard from the server-side. What you can do is programmably create a table, or use the Grid control. Or, try to make the table a server-side control, and see if that works well with the repeater (I don't think it will). Or, if you can say ignore the first two columns, make the table row within the repeater item a server-side row as in , and use FindControl to find the item and do something with it. You would have to work with the cell index though, to show/hide cells within the column.
HTH.

C#,ASP.NET: Formatting a GRIDVIEW row Based on Content

Greetings Gurus. I have a gridview who's rows I need to higlight if the 'Status' field is null. The code below throws an exception. I'm getting a "Non-invocable member 'System.Web.UI.WebControls.GridViewRow.DataItem' cannot be used like a method". I think I'm really close but I don't know where to turn next.
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow &&
e.Row.DataItem("Status") == null)
{
// e.Row.BackColor = Drawing.Color.Red;
}
}
basic
CType(e.Row.DataItem, DataRowView)("Status") = null
c#
((DataRowView)e.Row.DataItem)["Status"] == null
or do it in more than one line -- see example here:
msdn example
I haven't looked at this in a long while but do you access DataItem like an array??
e.Row.DataItem("Status") would be e.Row.DataItem["Status"]
Look here
// Retrieve the underlying data item. In this example
// the underlying data item is a DataRowView object.
DataRowView rowView = (DataRowView)e.Row.DataItem;
// Retrieve the state value for the current row.
String state = rowView["state"].ToString();
Try casting:
if (((MyType)e.Row.DataItem).Status == null) { ... }
Have a look at the sample code at MSDN.
The key points are:
Cast your DataRow to a DataRowView,
like this:
DataRowView rowView = (DataRowView)e.Row.DataItem;
You can then retrieve values like
this:
// Retrieve the status value for the current row.
Status status = (Status)rowView["status"];
...or cast to whatever type Status happens to be.
Got it. It may not be the best solution but it works.
if (e.Row.RowType == DataControlRowType.DataRow )
{
DataRowView test = (System.Data.DataRowView)e.Row.DataItem;
string Active = test.Row[4].ToString();
if(Active == "")
{
e.Row.BackColor = System.Drawing.Color.Sienna;
e.Row.ForeColor = System.Drawing.Color.Yellow;
}
}

ASP.net list of dropdownlists - similar to Access continuous form

What I'm looking for is a way to mimic the MS-Access style continuous form within asp.net. In one particular case, I want a control, bound to a datasource which returns a dropdownlist for each row, bound to the value within the datasource. Any change to any of the dropdownlists' would perform an update to the database instantly.
I have got halfway to achieving this using a repeater control, with the DropDownList.SelectedValue assigned within the Repeater.ItemDataBound event.
But now, supposing I add an OnSelectedIndexChanged event to the DropDownList - how would I then query the repeater to know which row I was on (to get the primary key value, for example)
I'm not sure this can be done easily.. so the question is what should I really be doing? I don't want to use a GridView that requires me to select a row to edit.. I just want to have the dropdownlists autopostback for any updates.
Hope that's clear?!
Cheers! :D
For examples sake, lets say we are binding to a custom class called Record
public class Record
{
public int Id;
public string Value;
}
If you put custom logic on the Repeater.OnItemCreated event you can attach the primary key to the id of the drop down list
protected void Repeater_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if (!(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem))
return;
var dataItem = e.Item.DataItem as Record;
if (dataItem == null) return;
var dropdown = e.Item.FindControl("myDropDown") as DropDownList;
if (dropdown == null) return;
dropdown.ID = dropdown.ID + dataItem.Id;
}
Then on the SelectedIndexChange, you can pull the id off of the dropdown that fired the event.
protected void SelectedIndexChanged(object sender, EventArgs e)
{
var dropdown = sender as DropDownList;
if (dropdown == null) return;
var stringId = dropdown.ID.Replace("myDropDown", "");
int id;
if (Int32.TryParse(stringId, out id))
{
updateRecord(id, dropdown.SelectedValue);
}
}
It's very much an ugly hack, but it should allow you to do what you want.
Easiest way to tackle this would be to mimic the Access continuous form ASP.NET style. Which would be to make a UserControl to handle the row-level UI, then put said UserControl in a repeater.

Resources