Dynamic Template Controls - asp.net

On !PostBack dynamic templates are created based on the number of rows needed for check boxes. The control id's are chkbox_id. I am unable to retrieve the dynamic check boxes via the following code and NullReferenceException is always thrown.
The code before loops through the gridview rows, then datatable dt references the possible number of dynamic columns.
for (int i = 0; i < dt.Rows.Count; i++)
{
string id = dt.Rows[i]["id"].ToString();
CheckBox cb = (CheckBox)row.FindControl("ckbox_" + id);
if (cb.Checked)
{ // do things }
}
Checkboxes defined here within page load:
if (!Page.IsPostBack)
{
foreach (DataRow dRow in dt.Rows)
{
TemplateField ckhColumn = new TemplateField();
ckhColumn.HeaderTemplate = new GridViewTemplate(ListItemType.Header, dRow["name"].ToString());
ckhColumn.ItemTemplate = new GridViewTemplate(ListItemType.Item, "ckbox_" + dRow["id"].ToString());
gvProductPriceList.Columns.Add(ckhColumn);
}
}
Let me know if I need to clarify anything else.

I'm not positive on this, and I don't have a minute to try it, but it might work if you do a row.Parent.FindControl(...). Also, if you use the as operator instead of a direct cast, you won't have the null reference exception (i.e. you can check for it):
CheckBox cb = row.Parent.FindControl("ckbox_" + id) as CheckBox;
if (cb != null)
{
// ...
}

Related

How can you force an ASP.Net GridView to display an EmptyDataTemplate given there's only a single data record with all blanks?

My stored procedure, instead of returning zero rows, returns one with most of the columns NULL. When my .Net code sees such data, I wish to force it to display the EmptyDataTemplate. How?
Thanks Win,
In the LinqDataSource Selecting event handler I check if the data source has a size of one and has a null value for one of the key fields and then I pass in this to the LinqDataSourceSelectEventArgs' Result:
using (var dataContext = new WebDataContext())
{
var report = from row in dataContext.GetReport()
select new Report()
{
AccountCode = row.AccountCode //,
//...
}
}
if (report.Count() == 1 && report.ToList()[0].AccountCode == null)
{
var emptyReport = report.ToList();
report.Clear();
e.Result = emptyReport;
}
else
{
//...
e.Result = matrixReport;
//...
}

CheckBoxList '.Selected' is returning false in every situation

I am trying to grab multiple values from a checkboxlist and add them to a list, But checked values are always false even though the list contains appropriate count value.
code to populate:
Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey;
HelpingOthersEntities helpData = new HelpingOthersEntities();
List<LookupStoreLocationsByUserName> theDataSet = helpData.LookupStoreLocationsByUserName(userGuid).ToList<LookupStoreLocationsByUserName>();
locCkBox.DataSource = theDataSet;
locCkBox.DataTextField = "slAddress";
locCkBox.DataValueField = "storeLocationID";
locCkBox.DataBind();
code for adding to list:
List<int> locList = new List<int>();
for (int x = 0; x < locCkBox.Items.Count; x++){
if(locCkBox.Items[x].Selected){
locList.Add(int.Parse(locCkBox.Items[x].Value));
}
}
The problem I am having is that I cannot get into items.selected
my value is always false.
I have tried populating the checkboxes from postback but i get the same result. My list gives me the appropriate .Count amount of values, but items.selected = false?
I have tried a foreach loop to add to list as well but I get the same results over and over. Am i missing an event or something?
I'm going to take a guess here and say that your code that does the population stuff is being called in the pageload event, so you have something like the following.
private void Page_Load()
{
Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey;
HelpingOthersEntities helpData = new HelpingOthersEntities();
List<LookupStoreLocationsByUserName> theDataSet = helpData.LookupStoreLocationsByUserName(userGuid).ToList<LookupStoreLocationsByUserName>();
locCkBox.DataSource = theDataSet;
locCkBox.DataTextField = "slAddress";
locCkBox.DataValueField = "storeLocationID";
locCkBox.DataBind();
}
If that's the case then your effectively writing over the postback data on each request. To sort this out you need to only perform the databinding when its not a postback, so you need to change the above code to
private void Page_Load()
{
if (!IsPostBack)
{
Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey;
HelpingOthersEntities helpData = new HelpingOthersEntities();
List<LookupStoreLocationsByUserName> theDataSet = helpData.LookupStoreLocationsByUserName(userGuid).ToList<LookupStoreLocationsByUserName>();
locCkBox.DataSource = theDataSet;
locCkBox.DataTextField = "slAddress";
locCkBox.DataValueField = "storeLocationID";
locCkBox.DataBind();
}
}
You should then be able to test the Selected property of the items. I'd also probably change the code your using to test for the selected to something like
List<int> locList = new List<int>();
foreach(var item in locCkBox.Items)
{
if(item.Selected)
{
locList.Add(int.Parse(item.Value));
}
}
or if your on a .NET version with LINQ available
List<int> locList = new List<int>();
(from item in locCkBox.Items where item.Selected == true select item).ForEach(i => locList.Add(i.Value));
Make sure while binding the checkboxlist in page load you have set this check.
if (!Page.IsPostBack)
{
...bind your data
}
This should do the trick.

ASP.NET How to retrieve a list of the empty labels on a page?

I have some labels on my Page (e.g. Label1...Label100).
I don't want to loop through all Labels to check if Text property is = "" (or string.Empty, whatever), so this's my question - is it possible to use LINQ or Lambda Expression to get all "empty" labels ?
You can find all the page controls through the Controls property
Page.Controls.OfType<Label>().Where(lbl => lbl.Text == "");
Note that this isn't recursive; i.e. if you have a PlaceHolder which has controls of its own, those will not be returned by Page.Controls.
You can make a "FindAllChildren" extension method that finds all controls recursively from some parent control (which could be the page), and have it return an IEnumerable<Control>. Then use a Linq query on that.
public static IEnumerable<Control> FindAllChildren(this Control control)
{
foreach(Control c in control.Controls)
{
yield return c;
foreach(control child in c.FindAllChildren()
yield return child;
}
}
var allEmptyLabels = parent.FindAllChildren().OfType<Label>()
.Where(l => l.Text == String.Empty);
Is that your label naming convention?
If so, this quick and dirty method could do:
List<Label> labels = new List();
for (int i = 0; i <= 100; i++)
{
var label = (Label)Page.FindControl("Label" + i);
if (label.Text != string.Empty)
labels.Add(label);
}
// use labels collection here
No LINQ, or Lambdas, but it's another perspective for you.

How do I Immediately Validate a Newly Inserted Row in a Silverlight 3 Datagrid?

I have a Silverlight 3 tools library with a custom DataGrid user control. This grid has no direct access to the WCF RIA Services entity types so I'm using reflection to add a new item when the user clicks on the grid when it's empty:
private void InsertEmptyRecord()
{
if (this._dataGrid.ItemsSource == null)
return;
Type[] typeParameters = this._dataGrid.ItemsSource.GetType().GetGenericArguments();
if (typeParameters.Count() > 0)
{
Type itemType = typeParameters[0];
object newItem = System.Activator.CreateInstance(itemType);
Type sourceType = typeof(System.Windows.Ria.EntityCollection<>);
Type genericType = sourceType.MakeGenericType(itemType);
System.Reflection.MethodInfo addMethod = genericType.GetMethod("Add");
addMethod.Invoke(this._dataGrid.ItemsSource, new object[] { newItem });
// == Validate data here ==
}
}
This works, but I need it to also validate after the new item is added. There are two ways I can see to do this:
Force the user to enter edit mode
for the first cell of the new row in
the grid. (This would force
validation if they click anywhere
else on the page.)
Force validations
to run immediately when the new row
is added (or when the grid looses
focus.)
I haven't been able to get either of these to work. Tried this but it only selects the row, doesn't force the validations to run:
this._dataGrid.SelectedItem = newItem;
System.ComponentModel.IEditableObject editableItem = newItem as System.ComponentModel.IEditableObject;
if (editableItem != null)
editableItem.BeginEdit();
Any suggestions?
Just got this working thanks to some help from this question.
I added the following to the "== Validate data here ==" section in the code from above:
DataGridRow newRow = this._dataGrid.ChildrenOfType<DataGridRow>().FirstOrDefault();
if (newRow != null)
{
newRow.Loaded += (sender, e) =>
{
this._dataGrid.CurrentItem = newItem;
this._dataGrid.BeginEdit();
};
}
This forces the first cell to immediately go into edit mode.

Return ASP DDL or Telerik control

I'm trying to write a more generic method that will populate either an ASP.NET dropdownlist OR a telerik RadComboBox with states. I'd like to pass the control in as a parameter to the method. I have a DataTable that holds all the states, which I loop through (see below) - I'd like to make this applicable to a Telerik RadComboBox - so I need to change the first parameter, and also the part where I Insert a new ListItem - for Telerik RadComboBox it is new RadComboBoxItem. How can I do this?
public void PopulateStates(DropDownList ddlStates, string country)
{
ddlStates.Items.Clear();
DataLookup dl = new DataLookup();
DataTable dt = dl.GetStatesByCountry(country);
if (dt != null)
{
if (dt.Rows.Count > 0)
{
ddlStates.Items.Insert(0, new ListItem(""));
for (int i = 0; i < dt.Rows.Count; i++)
{
ddlStates.Items.Add(new ListItem(dt.Rows[i]["STCD_Descr"].ToString(),
dt.Rows[i]["STCD_State_CD"].ToString()));
}
}
}
}
I looked up the telerik documentation & there doesn't seem to be common way of doing - what you are trying to do.
If it is possible, try using the databinding (setting the DataSource & calling DataBind).
Note: I haven't tried it. But I think that should be supported by both.
Since ListBox and RadComboBox does not have common classes except for the "Control" class you will need to check the actual type.
How about the following code?
public void PopulateStates(Control ddl, string country)
{
object listItem = new object();
switch (ddl.GetType().Name)
{
case "RadComboBox":
listItem = listItem as RadComboBoxItem;
ddl = ddl as RadComboBox;
break;
case "ListBox":
listItem = listItem as ListItem;
ddl = ddl as ListBox;
break;
default:
return;
}
// proceed with your code
}

Resources