How to Bind complex data to control in ListView (class User contain instance of class UserType) - asp.net

I have 2 value class
public class UserType
{
public int ID;
public string TypeName;
}
public class User
{
public int ID;
public string UserName;
public UserType Type;
}
1 proccessing class
public class Users
{
public User[] GetUsers()
{
//Retrive and re turn User array
}
public int Update(User user, User old_user)
{
//Update user
}
}
1 ListView and 1 ObjectDataSource
<asp:ListView ID="lsvUser" runat="server" DataKeyNames="ID" DataSourceID="odsUser"
ItemPlaceholderID="plhItem" onitemupdating="lsvUser_ItemUpdating">
<LayoutTemplate>
<ul><asp:PlaceHolder ID="plhItem" runat="server"></asp:PlaceHolder></ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:Label ID="lblID" runat="server" Text='<%# Eval("ID") %>'></asp:Label>
<asp:Label ID="lblUserName" runat="server" Text='<%# Eval("UserName") %>'></asp:Label>
<asp:Label ID="lblTypeName" runat="server" Text='<%# Eval("Type.TypeName") %>'></asp:Label>
<asp:LinkButton ID="btEdit" runat="server" CssClass="button" CommandName="Edit" Text="Edit"></asp:LinkButton>
</li>
</ItemTemplate>
<EditItemTemplate>
<li class="editRow">
<asp:Textbox ID="txbUserName" runat="server" Text='<%# Bind("UserName") %>'></asp:Textbox >
<asp:Textbox ID="txbTypeName" runat="server" Text='<%# Bind("Type.TypeName") %>'></asp:Textbox >
</li>
</EditItemTemplate>
</asp:ListView>
<asp:ObjectDataSource ID="odsUser" runat="server" TypeName="BLL.Users" DataObjectTypeName="BLL.User" SelectMethod="GetUsers" UpdateMethod="Update" ConflictDetection="CompareAllValues" OldValuesParameterFormatString="old_{0}"></asp:ObjectDataSource>
When data is loaded into the ItemTemplate, the ListView interprets Type.TypeName and binds correctly,
but when updating the record, I cannot retrieve the old_user.Type from the old values. So old_user.Name and old_user.ID have values but old_user.Type is null.
Help me. I have been searching for about 2 days and cannot find a solution. I can bind data for a new user like this:
protected void lsvUser_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
e.NewValues.Add("Type", new BLL.UserType() { TypeName = Convert.ToString(((TextBox)lsvUser.EditItem.FindControl("txbTypeName")).Text) });
}
But I don't know how to retrieve the old values (how to retrive value of lblTypeName).
Help me. If there is a solution that doesn't require additional code in the ItemUpdating event, please teach me.
Thank you.

Add Type.TypeName as a DataKey, like this:
<asp:ListView ID="ListView1" runat="server" DataKeyNames="Type.TypeName">
And in your ItemUpdating event handler, retrieve the key value like this:
string typeName = (string)e.Keys["Type.TypeName"];
I'm not positive that "Type.TypeName will work, but some variation of that should work, whether it's Type.TypeName or just TypeName.

Related

How to string concatenate two bindings in asp.net?

I would like to string concatenate two bindings into one string. How can I do this? I tried the below, but only LastName shows up when I run the application.
<asp:Label ID="txtFacultyName" runat="server" Text='<%#Bind("FirstName") + Bind("LastName") %>'/>
There are a couple of options.
Create a combined property in your code behind/model:
// cs
public string FullName
{
get { return $"{FirstName} {LastName}"; }
}
// aspx
<asp:Label ID="txtFacultyName" runat="server" Text='<%#Bind("FullName") %>'/>
Use Eval. Eval will allow one-way binding which is fine for displaying in an asp:Label
<asp:Label ID="txtFacultyName"
runat="server"
Text='<%# string.Format("{0} {1}", Eval("FirstName"), Eval("LastName")) %>'/>

How to pass an repeating object to an user control into repeater

For example I use telerik rad grid, and bind list of users to it
rgUsers.DataSource = GetUsersList();
rgUsers.DataBind();
I have user control UserEditor that receives User object,
<radG:RadGrid runat="server" ID="rgUsers">
<MasterTableView>
<Columns>
<radG:GridTemplateColumn>
<ItemTemplate>
<asp:Label runat="server" ID="lblName" Text='<%# Eval("username") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<uc:UserEditor ID="UserEditor" runat="server" User='???????' />
</EditItemTemplate>
</radG:GridTemplateColumn>
...
Can I pass an User object to the UserEditor, or I must to make it in Data Binding event?
I think it works like native ASP.NET controls:
RadControls for ASP.NET AJAX Documentation - Event sequence
<radG:RadGrid runat="server" ID="rgUsers" OnItemDataBound="rgUsers_ItemDataBound">
protected void rgUsers_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item.ItemType == GridItemType.EditItem)
{
User user = (User)e.Item.GridDataItem;
UserEditor userEditor = (UserEditor )e.Item.FindControl("UserEditor");
UserEditor.User = user;
}
}

How to call a code-behind method from aspx page?

I've an object that contains a field called DevList which is defined like this
public List<string> DevList { get; set; }
I also defined a method called DisplayListOfDevelopers that is supposed to concatenate the list of developers and display it as a one string.
This is how I'm calling the method from aspx.
<asp:TemplateField HeaderText = "Developer(s)">
<ItemTemplate>
<asp:Label
ID="_lblDevList"
runat="server"
Text= '<%# DisplayListOfDevelopers(DevList) %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
But, I'm getting this error: The name 'DevList' does not exist in the current context
Am I missing something?
EDIT
_gvStatus = ds;
_gvStatus.DataBind();
Where ds is just a list of objects that contains the DevList for now.
Thanks for helping
Assuming this is how your class looks:
public class MyItem
{
public List<string> DevList { get; set; }
}
And that
ds = List<MyItem>();
Do this:
In your code-behind:
protected string DisplayListOfDevelopers(object _devList)
{
//Cast your dev list into the correct object
}
In your markup:
<asp:TemplateField HeaderText="Developer(s)">
<ItemTemplate>
<asp:Label
ID="_lblDevList"
runat="server"
Text='<%# DisplayListOfDevelopers(Eval("DevList")) %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
Just be sure to make the function in your code-behind is protected or public.

How to get item click event in asp.net repeater control?

I am using a repeater control to show some data on my page.
The repeater item template has an image and a label field.
I want that when i click the image , I get an event containing the id field of my data item.
How can I achieve this ?
Actually when I click the image i want to go to another page and want to show detailed information of my data item, in repeater i m just showing short information.
My repeater looks like this:
<asp:Repeater ID="itemRepeater" runat="server" OnItemCreated="itemRepeater_ItemCreated" >
<ItemTemplate>
<tr>
<td colspan="2">
<asp:Image ID="phImage" runat="server" ImageUrl='<%#"~/ImageHandler.ashx?id=" + DataBinder.Eval(Container.DataItem, "PhotoID")%>' />
</td>
<td>
<asp:Label ID="lblImageName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
I want to get PhotoID in the event when i click the image.
My photo class looks like this:
public class PhotoDC
{
public byte[] ImagebyteArray { get; set; }
public string Name { get; set; }
public int PhotoID { get; set; }
}
I have been doing winform programming just started web, maybe it is easy but i m struggling to find a solution.
I somehow managed to show hand cursor when i hover the image though.
Try this:
<asp:Repeater ID="itemRepeater" runat="server" OnItemCreated="itemRepeater_ItemCreated" >
<ItemTemplate>
<tr>
<td colspan="2">
<asp:ImageButton ID="phImage" runat="server" ImageUrl='<%#"~/ImageHandler.ashx?id=" + DataBinder.Eval(Container.DataItem, "PhotoID")%>' OnCommand="Image_Click" CommandName="ImageClick" CommandArgument='<%# Eval("PhotoID") %>' />
</td>
<td>
<asp:Label ID="lblImageName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
protected void Image_Click(object sender, CommandEventArgs e)
{
if (e.CommandName == "ImageClick"){
//e.CommandArgument --> photoid value
//Do something
}
}
You can use ItemCommand of repeater control
like this -
protected void itemRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (e.CommandName == "img_Click") // check command is cmd_delete
{
// get you required value
int CustomerID = Convert.ToInt32(e.CommandArgument);
//Write some code for what you need
}
}
}
Personally I think the simplest way to handle something like this is to simply use the ItemTemplate to generate a regular html link, rather than do any thing in the code-behind. Something like this:
<asp:Repeater ID="itemRepeater" runat="server" OnItemCreated="itemRepeater_ItemCreated" >
<ItemTemplate>
<tr>
<td colspan="2">
<a href="/Details.aspx?id=<%=DataBinder.Eval(Container.DataItem, "PhotoID")%>">
<asp:Image ID="phImage" runat="server" ImageUrl='<%#"~/ImageHandler.ashx?id=" + DataBinder.Eval(Container.DataItem, "PhotoID")%>' />
</a>
</td>
<td>
<asp:Label ID="lblImageName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
</td>
</tr>
</ItemTemplate>
I know this isn't strictly the question you asked, but IMHO it's the best approach to accomplish the task.

calling a function in repeater asp.net

I want to call a function to bind data to Repeater . Do I need to Set dataSource Property of this control or Repeater .DataBind() will work.
<asp:Repeater ID="RepeaterDays" runat="server">
<ItemTemplate>
<ul>
<asp:Label ID="lblDays" runat="server" Text='<%#ChandanIdiot()%>'></asp:Label>
</ul>
</ItemTemplate>
</asp:Repeater>
I have written RepeaterDays.Databind(), but the function is not called.
This is displaying nothing.
Is ChandanIdiot() a protected function that returns a string?
protected string ChandanIdiot() {
return "test";
}
If you want to actually do some data processing, you will have to include a parameter:
protected string ChandanIdiot(object obj) {
return "test " + obj;
}
And, assuming that there is a property called "Name" on the object that you are reapeating, you would have the following:
<asp:Label ID="lblDays" runat="server" Text='<%# ChandanIdiot(Eval("Name")) %>' />
Source:
<asp:TemplateField HeaderText="Unit Price">
<ItemTemplate>
<%# ChandanIdiot( Eval("product_unitprice"))%>
<!--product_unitprice is table colomn name -->
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox4" runat="server" ></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
C#:
protected string ChandanIdiot(object ob) {
string typ = ob.ToString(); //selected value stored in ob
if (typ == "some function") {
//do somthing
}
return typ ; //value return to <%# ChandanIdiot( Eval("product_unitprice"))%>
}

Resources