Grid view binding - asp.net

I am binding an Object datasource to a grid view. My object has a collection of items in one of the properties.Which is a List. How do I Loop thru this and bind the items to a column in GridView?.

Get the Collection from the object and bind it by using
myGridView.DataSource = myCollection;
myGridView.DataBind();

Edit: updated to call a method in the code behind to generate html markup for the collection.
In your aspx markup you could have something like the following:
<asp:GridView ID="myGridView" AutoGenerateColumns="False" runat="server">
<Columns>
<asp:BoundField HeaderText="Item Name" DataField="Name" />
<asp:TemplateField HeaderText="Collection Field">
<ItemTemplate>
<%# ((_Default)Page).GetHtmlForList(DataBinder.Eval(Container.DataItem, "List"))%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
then in your code behind you could have something like this:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
myGridView.DataSource = GetCollection();
myGridView.DataBind();
}
}
public string GetHtmlForList(object value)
{
string html = "";
List<string> list = (List<string>)value;
foreach (string item in list)
html += item + "<br/>";
return html;
}
private List<MyClass> GetCollection()
{
List<MyClass> coll = new List<MyClass>();
coll.Add(new MyClass { Name = "First Item", List = new List<string>(new string[] { "1", "2", "3" }) });
coll.Add(new MyClass { Name = "Second Item", List = new List<string>(new string[] { "Apples", "Pears", "Oranges" }) });
coll.Add(new MyClass { Name = "Third Item", List = new List<string>(new string[] { "Red", "Green", "Blue" }) });
return coll;
}
}
public class MyClass
{
public string Name { get; set; }
public List<string> List { get; set; }
}

Could you not have a Repeater inside the Col. template, and simply bind your List to it in the RowDataBound?

Related

Type UserControl does not have a public property named Columns

I'm trying to develop a UserControl containing a GridView inside a Panel
<asp:Panel runat="server" ID="panel">
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="false">
</asp:GridView>
</asp:Panel>
Code behind
public partial class DropDownMultiColumn : UserControl
{
[System.Web.UI.IDReferenceProperty(typeof(DataControlFieldCollection))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual DataControlFieldCollection Columns
{
get { return gridView.Columns; }
set
{
gridView.Columns.Clear();
foreach (DataControlField c in value)
{
gridView.Columns.Add(c);
}
}
}
}
I've included the control into a ASPX page, using the Columns public property
<dd:DropDownMultiColumn id="_dd_InsertStore" runat="server" DataSourceID="_dsTest" >
<Columns>
<asp:BoundField DataField="MGCOD" HeaderText="MGCOD"></asp:BoundField>
<asp:BoundField DataField="MGDSC" HeaderText="MGDSC"></asp:BoundField>
</Columns>
</dd:DropDownMultiColumn>
But I get the following error in Design section:
Type 'System.Web.UI.UserControl' does not have a public property named 'Columns'
I've tried to implement this solution, but it doesn't work. Any ideas?
Here follows a working workaround for the issue.
Declare a property with JSON content
Declare Columns as an attribute, containing required data in JSON format
<dd:DropDownMultiColumn id="_ddInsertStore" runat="server" DataSourceID="_dsTest" Columns="
[{ 'DataField':'MGCOD', 'HeaderText':'MGCOD' },
{ 'DataField':'MGDSC', 'HeaderText':'MGDSC' }]">
</dd:DropDownMultiColumn>
Convert JSON to BoundField
Within OnLoad event, deserialize JSON and build BoundField data
protected override void OnLoad(EventArgs e)
{
List<Column> columns = JsonConvert.DeserializeObject<List<Column>>(Columns);
gridView.Columns.Clear();
foreach (Column column in columns)
{
BoundField boundField = new BoundField();
boundField.DataField = column.DataField;
boundField.HeaderText = (string) column.HeaderText;
gridView.Columns.Add(boundField);
}
}
Declare a Column class, having the required properties.
public class Column
{
public string DataField { get; set; }
public string HeaderText { get; set; }
}

Using ASPxComboBox with ASPxGridView, need to set initial value

I'm trying to use ASPxGridView to display a list of ASPxComboBox controls. Both the rows in the grid and the list of options in the combo boxes are populated from code. I'm having problems setting the initial value of the combo boxes.
I'm looking for it to look similar to the image below.
As you can see in the screenshot, I have been able to get both the grid view & the combo boxes to populate, but I can't figure out how to set the initial values of the combo boxes.
In the Init event of the inner combo boxes, there's no obvious property to retrieve the bound object.
I did find a couple other questions on StackOverflow, for which the answer was to add a bound property to the combo box. However, adding SelectedIndex='<%# Bind("Level") %>' to the declaration for InnerCombo gave me the error "Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control."
Here's what I have so far:
Testing.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Light.master"
AutoEventWireup="true" CodeBehind="Testing.aspx.cs" Inherits="MyProject.Testing" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<dx:ASPxGridView ID="MyGridView" runat="server" KeyFieldName="Name">
<Columns>
<dx:GridViewDataColumn FieldName="Name" />
<dx:GridViewDataColumn FieldName="Level">
<DataItemTemplate>
<dx:ASPxComboBox
runat="server"
ID="InnerCombo"
ValueField="ID"
TextField="Desc"
ValueType="System.Int32"
OnInit="InnerCombo_Init" />
</DataItemTemplate>
</dx:GridViewDataColumn>
</Columns>
</dx:ASPxGridView>
<dx:ASPxButton runat="server" ID="btnSubmit" Text="Submit" OnClick="btnSubmit_Click" />
</asp:Content>
Testing.aspx.cs:
public partial class Testing : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.MyGridView.DataSource = GetDefaultSettings();
this.MyGridView.DataBind();
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
Debug.WriteLine("btnSubmit_Click");
for (int i = 0; i < MyGridView.VisibleRowCount; i++)
{
object[] row = (object[])MyGridView.GetRowValues(i, "Name", "Value");
// row[1] is null, but we can get the data by finding the combo box itself.
GridViewDataColumn col = (GridViewDataColumn)MyGridView.Columns["Value"];
ASPxComboBox innerCombo = (ASPxComboBox)MyGridView.FindRowCellTemplateControl(i, col, "InnerCombo");
Debug.WriteLine("{0} = {1}", row[0], innerCombo.Value);
}
}
protected void InnerCombo_Init(object sender, EventArgs e)
{
Debug.WriteLine("InnerCombo_Init");
ASPxComboBox innerCombo = sender as ASPxComboBox;
if (innerCombo != null)
{
innerCombo.DataSource = GetValues();
innerCombo.DataBind();
}
}
private static List<ValueClass> GetValues()
{
// Simple for testing; actual method will be database access.
return new List<ValueClass>()
{
new ValueClass(0, "Zero (default)"),
new ValueClass(1, "One"),
new ValueClass(2, "Two"),
new ValueClass(3, "Three"),
};
}
private static List<SettingClass> GetDefaultSettings()
{
// Simple for testing; actual method will be database access + post-processing.
return new List<SettingClass>()
{
new SettingClass("AA", 0),
new SettingClass("BB", 1),
new SettingClass("CC", 0),
};
}
public class ValueClass
{
public int ID { get; private set; }
public string Desc { get; private set; }
public ValueClass(int id, string desc)
{
this.ID = id;
this.Desc = desc;
}
}
public class SettingClass
{
public string Name { get; set; }
public int Value { get; set; }
public SettingClass(string name, int value)
{
this.Name = name;
this.Value = value;
}
}
}

Custom user control data source

I have a custom control that has a DropDownList inside and it's created by CreateUserControl. I'm saving data source directly to dropdown control. After page postbacked my binded data disappear. Should i save/restore my binded data myself in some tricky way?
public class EnumDropDownList : UserControl
{
private readonly DropDownList _ddlSelector;
private Dictionary<long, string> _dataSource;
public EnumDropDownList()
{
_ddlSelector = new DropDownList();
_dataSource = new Dictionary<long, string>();
}
public object DataSource
{
set
{
// datasource logic
}
}
public long SelectedValue
{
get { return Convert.ToInt64(_ddlSelector.SelectedValue); }
set { _ddlSelector.SelectedValue = value.ToString(); }
}
public override void DataBind()
{
_ddlSelector.DataSource = _dataSource;
_ddlSelector.DataTextField = "Value";
_ddlSelector.DataValueField = "Key";
_ddlSelector.DataBind();
base.DataBind();
}
[PermissionSet(SecurityAction.Demand, Name = "Execution")]
protected override void CreateChildControls()
{
Controls.Add(_ddlSelector);
}
}
You code is combination of UserControl and CustomServerControl.
It could have be a lot easier if you implement one instead of combination.
I created two controls - UserControl and CustomServerControl.
UserControl
Place the dropdownlist to ASPX instead of loading dymaiclally. If you load dynamically, you'll have to take care of persistence of control.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="EnumDropDownList.ascx.cs"
Inherits="WebApplication2010.EnumDropDownList" %>
<asp:DropDownList runat="server" ID="DropDownList1" />
public partial class EnumDropDownList : System.Web.UI.UserControl
{
private Dictionary<long, string> _dataSource;
public EnumDropDownList()
{
_dataSource = new Dictionary<long, string>();
}
public Dictionary<long, string> DataSource
{
set { _dataSource = value; }
}
public long SelectedValue
{
get { return Convert.ToInt64(DropDownList1.SelectedValue); }
set { DropDownList1.SelectedValue = value.ToString(); }
}
public override void DataBind()
{
DropDownList1.DataSource = _dataSource;
DropDownList1.DataTextField = "Value";
DropDownList1.DataValueField = "Key";
DropDownList1.DataBind();
base.DataBind();
}
}
Custom Server Control (it is a lot easier to implement for your case)
It basically inherits DropDownList web control.
public class MyDropDownList : DropDownList
{
public long SelectedInt64Value
{
get { return Convert.ToInt64(SelectedValue); }
set { SelectedValue = value.ToString(); }
}
public Dictionary<long, string> DataSource
{
get { return (Dictionary<long, string>)ViewState["DataSource"]; }
set { ViewState["DataSource"] = value; }
}
public override void DataBind()
{
foreach (var item in DataSource)
Items.Add(new ListItem(item.Value, item.Key.ToString()));
base.DataBind();
}
}
Usage
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm5.aspx.cs" Inherits="WebApplication2010.WebForm5" %>
<%# Register Src="EnumDropDownList.ascx" TagName="EnumDropDownList" TagPrefix="uc1" %>
<%# Register TagPrefix="asp" Namespace="WebApplication2010" Assembly="WebApplication2010" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<uc1:EnumDropDownList ID="EnumDropDownList1" runat="server" />
<asp:Button runat="server" ID="Button1" Text="Submit" OnClick="Button1_Click" />
<asp:MyDropDownList id="MyDropDownList1" runat="server" />
</form>
</body>
</html>
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Dictionary<long, string> dataSource = new Dictionary<long, string>();
dataSource.Add(1, "One");
dataSource.Add(2, "Two");
EnumDropDownList1.DataSource = dataSource;
EnumDropDownList1.DataBind();
MyDropDownList1.DataSource = dataSource;
MyDropDownList1.DataBind();
}
}
In some cases I have saved the dataset in a session variable. Whicn can then be referenced after postbacks. Something like this:
Session.Add("dataSource", _dataSource);//create the session variable
Then you can reference it, depending on the type the data source is (in example I used a datable)
_ddlSelector.DataSource = (DataTable)Session["dataSource"];
THis Is aspx file :
<telerik:RadComboBox ID="cmbCurrency" runat="server" Width="200px" MaxHeight="200px"
EmptyMessage="Select a currency" AutoPostBack="true" Filter="Contains" EnableLoadOnDemand="true">
</telerik:RadComboBox>
This is code Behind :
if (!IsPostBack)
{
popCurrencyName();
}
public void popCurrencyName()
{
DataTable dtCurrency = objCurrencyBAL.getCurrency(long.MinValue);
if (dtCurrency.Rows.Count > 0)
{
cmbCurrency.DataSource = dtCurrency;
cmbCurrency.DataTextField = "Name";
cmbCurrency.DataValueField = "CurrencyId";
cmbCurrency.DataBind();
}
}
Try this code:

Databinding repeater. Property not found

Why am i getting the error that
DataBinding: _Default+Student does not contain a property called name.
This is my CodeBehind:
public class Student
{
public string name ="Name";
public string favouriteFood = "Favourite food";
public string hobby = "Hobby";
}
protected void Page_Load(object sender, EventArgs e)
{
Student nino = new Student();
nino.name = "nino";
nino.favouriteFood = "nachos";
nino.hobby = "dancing son";
Student madelene = new Student();
madelene.name = "madelene";
madelene.favouriteFood = "sushi";
madelene.hobby = "dancing casino";
Student baiba = new Student();
baiba.name = "baiba";
baiba.favouriteFood = "bitch soup";
baiba.hobby = "complaining";
ArrayList students = new ArrayList();
students.Add(madelene);
students.Add(nino);
students.Add(baiba);
testRepeater.DataSource = students;
testRepeater.DataBind();
}
This is the front:
<asp:Repeater runat="server" ID="testRepeater" >
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "name") %>' />"></asp:Label>
</ItemTemplate>
</asp:Repeater>
Convert the public variable name into a property like:
private string _name;
public string name
{
get
{
return _name??"Name";
}
set
{
_name = value;
}
}
It can be an auto property, if you dont need a default value ("Name") like:
public string name {get;set;}

asp.net gridview binding to deeper property of specific type

my webside has a gridview
i bind it to a dataset recived from powershell
in this dataset are a lot of different data types.
everything is working fine but for one field i would like to bind a deeper property to the boundfield!
i bind it like this:
c#
GridViewAgentGroups.DataSource = dt;
GridViewAgentGroups.DataBind();
Markup
<asp:BoundField DataField="Name" HeaderText="Name" ReadOnly="True" />
<asp:BoundField HeaderText="Service" ReadOnly="True"
DataField="Identity" />
<asp:BoundField DataField="Description" HeaderText="Description"
ReadOnly="True" />
the boundfield of service binds to data of type: "Microsoft.Rtc.Rgs.Management.RgsIdentity"
it contains an instanceID and serviceID propertyand the serviceID contains a property fullName!
when i bind it directly like "DataField="Identity" it shows a very long string with the fullName included!
is there a way to only bind the fullName? like "DataField="Identity.ServiceID.FullName"? in xml? (this does not work :-)
Yes it is possible with TemplateFields but it depends upon the dataSource design too. Have a look at this sample:
Markup:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<%#Eval("Name") %>
<%#Eval("GroupName.Name") %>
<%#Eval("GroupName.RegionName.Name") %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind:
public class Region
{
public string Name { get; set; }
}
public class Group
{
public string Name { get; set; }
private Region _region=new Region();
public Region RegionName { get { return _region; } set { _region = value; } }
}
public class Product
{
public string Name { get; set; }
private Group _groupName = new Group();
public Group GroupName { get { return _groupName; } set { _groupName = value; } }
}
public class Products : List<Product>
{
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Region reg1 = new Region() { Name = "North" };
Region reg2 = new Region() { Name = "East" };
Group group1 = new Group() { Name="Group1", RegionName=reg1 };
Group group2 = new Group() { Name = "Group2", RegionName=reg1 };
Group group3 = new Group() { Name = "Group3", RegionName = reg2 };
Products prod = new Products()
{
new Product(){ Name="Product1", GroupName=group1},
new Product(){ Name="Product1", GroupName=group2},
new Product(){ Name="Product2", GroupName=group3},
new Product(){ Name="Product3", GroupName=group1},
new Product(){ Name="Product2", GroupName=group2},
};
GridView1.DataSource = prod;
GridView1.DataBind();
}
}

Resources