How to do a data lookup field in a DetailsView? - asp.net

I have a master-detail page for Customers. Select a customer from the list and a details view opens with Name, Address...etc.
I've been asked to add a field listing the Sales Rep servicing that customer.
I want the new field to hold the foreign key to the SalesRep table: the SalesRepID. An integer.
I am not sure how to "wire up" the ItemTemplate field for displaying the Sales Rep name in a label. Also not sure about the EditItemTemplate dropdown list of possible Sales Reps.
I know I need to create a datasource to retreive the Sales Reps into a dataSet.
Let's call it "SQL_Reps_source".
A DropDownList seems to only like a list of values, and doesn't seem to handle Keys and Values like a HashTable or SortedList would.
Any advice on how to go about this?
Thanks

The following example adds a DropDownList to the EditItemTemplate of the DetailsView. The DataSourceID is set to the data source control that retrieves the sales reps names and id's.
<asp:TemplateField HeaderText="Sales Rep">
<EditItemTemplate>
<asp:SqlDataSource ID="SqlDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:MyConnectionString %>"
SelectCommand="SELECT SalesRepID, SalesRepName FROM SalesReps">
</asp:SqlDataSource>
<asp:DropDownList ID="DropDownList" Runat="server"
DataTextField="SalesRepName" DataValueField="SalesRepID"
SelectedValue='<%# Bind("SalesRepID") %>'
DataSourceID="SqlDataSource">
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label" Runat="server"
Text='<%# Bind("SalesRepName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>

For display purposes - return the NAME of the Sales Rep. rather than ID
DropDownList (ddl) handles both Values and Keys just fine, the naming is a bit off though. ddl.DataTextField property will hold the Name, ddl.DataValueField property will hold the ID. (see this answer for more details on this)
In the EditTemplate you'd need to fill the DropDown as described above, and then set its SelectedValue to the ID of Sales Rep. in quesion.
Hope this helps.

When you bind the dropdownlist do this:
ddl.DataSource = SQL_Reps_source;
ddl..DataTextField = "fullname";
ddl..DataValueField = "id";

Related

Setting a dictionary as datasource

I have the following dictionary and like to set this as the datasource to my Gridview in my asp.net page
Dim myList As New Dictionary(Of Person, string)
the dictionary key is an object of Person which has Id,FirstName and LastName.
and I like to bind the above dictionary to a gridview which shows First name, Last name and Address
<asp:TemplateField HeaderText="First Name" SortExpression="FirstName">
<EditItemTemplate>
<asp:TextBox ID="txtFName" runat="server" Text='<%# Bind("FirstName")%>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
the next column will be last name and the third will be the address - which is the value property of dictionary
is it possible to bind the above dictionary to a gridview at all?
Thank you.
Your Dictionary is made up of KeyValuePair elements, which exposes two properties: Key and Value.
Since you want to bind items that are accessible through the Key property of each Dictionary entry, you should reference these properties in your databinding as Key.FirstName, Key.LastName, Key.Address, etc.
So given your example above, binding the TextBox should look like:
<asp:TextBox ID="txtFName" runat="server" Text='<%# Bind("Key.FirstName")%>'></asp:TextBox>

How to populate a dropdown list in asp.net from a DB table?

I want to populate a dropdown list with values from a table I created. I only want to populate the list with one of the fields- the languages in my table. I think I have connected to the data source correctly, but I don't know what I have to do to get the values into the list. I can enter my own values but I'd rather have this automated.
This is what I have so far, but I'm guessing there's more to it than just linking the list to the data source.
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:HBshareIndexConnectionString %>"
SelectCommand="SELECT * FROM [Web_Metrics] WHERE ([LCID] = #LCID)">
<SelectParameters>
<asp:QueryStringParameter Name="LCID" QueryStringField="LCID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
<asp:Label ID="Label1" runat="server" Text="Select LCID: " ></asp:Label>
<asp:DropDownList ID="DropDownList1" Width="150px" runat="server" DataSourceID="SqlDataSource1" DataTextField="LCID" DataValueField="LCID">
<asp:ListItem>Select LCID...</asp:ListItem>
</asp:DropDownList>
Thanks for the help. I got the dropdown list populated now, but I was wondering how do I actually get the repeater I'm using to display the details of the LCID the person selects? I've seen people talking about page.isPostback but I don't know what that is or if it works with my current setup. I need to somehow get the LCID they selected and then refresh the page to show the details of that LCID. Does anyone have any ideas?
Your problem is that you're trying to define list items and a data source.
If you want to insert a "Select an item.." option, I would suggest prepending it to your resultset (getting it to always be first with a UNION and ORDER BY could be difficult depending on your fields) or inserting it after databinding in your code behind:
Modification to DropDownList1s attributes:
<asp:DropDownList ID="DropDownList1" Width="150px" runat="server" DataSourceID="SqlDataSource1" DataTextField="CountryName" DataValueField="LCID" OnDataBound="InsertChooseItem" />
C#:
protected void InsertChooseItem(object sender, EventArgs e)
{
ListItem selectOnePlease = new ListItem("Select LCID..", 0);
DropDownList1.Items.Insert(0, selectOnePlease);
}
VB:
Protected Sub InsertChooseItem(sender As Object, e As EventArgs)
Dim selectOnePlease As New ListItem("Select LCID..", 0)
DropDownList1.Items.Insert(0, selectOnePlease)
End Sub
You've specified the select parameter to be a query string, so the data in your DropDownList will only be populated when the URL resembles something like:
http://{Your server name}/Default.aspx?LCID=1
That doesn't make any sense though because the LCID column in your table should be unique, so although this will work there will only be one value in the drop down list.
I think what you want is to display all the languages from the database in the drop down, here's an example:
<asp:SqlDataSource ID="sqlDS" runat="server"
ConnectionString="<%$ ConnectionStrings:HBshareIndexConnectionString %>"
SelectCommand="SELECT LCID,Language FROM [Web_Metrics]">
</asp:SqlDataSource>
<asp:DropDownList ID="ddlLanguages" AppendDataBoundItems="true" Width="150px" runat="server" DataSourceID="sqlDS" DataTextField="Language" DataValueField="LCID">
<asp:ListItem>Select Language</asp:ListItem>
</asp:DropDownList>
Just a note, you should never display the ID to the client, it's totally meaningless to them, the ids are mostly used by developers in the background that's why in the drop down I set the:
DataTextField="Language" (This is the language name visible to the user)
DataValueField="LCID" (Not visible to the user, but useful for any additional processing in code behind)
AppendDataBoundItems="true" - this line of code will keep all the items you've manually added to the drop down, e.g "Select Language" and will append any data bound items e.g from a SQL table

Deleting Record Using ASP.NET Repeater and Entity Framework

I have an entity called PendingPartners which has a navigation property to the Residents entity. I'm returning information from these objects like so:
Dim getSent = (From p In dbContext.PendingPartners _
Join r In dbContext.Residents _
On p.people_id_des Equals r.people_code_id _
Where p.people_id_ini = people_id _
Where p.semester = semester _
Where p.year = year _
Select r.person_name).Distinct
rptrSent.DataSource = getSent
rptrSent.DataBind()
As you can see above, the data is then bound to a repeater control the code for which looks like this:
<asp:Repeater ID="rptrSent" runat="server">
<ItemTemplate>
<asp:Button ID="btnDeletePartner" runat="server"
Text="<%# Container.DataItem %>" />
<br />
</ItemTemplate>
</asp:Repeater>
Now, I want to make it so that when someone clicks the Delete button it actually deletes that record from the entity - just the PendingPartner portion, no need to rollup to the Resident object.
Now, to do this I think I need to:
Add the ID column to the EntitySQL query, e.g. Select p.id, r.person_name.
Bind the ID column to the repeater as say CommandName or CommandArgument.
Change the way the binding is for the text - since the repeater now has two columns.
I know how to update the EntitySQL, but I always get confused with then getting this info. into the repeater...help?
I think your need to use the bind function in the repeater
The Button's Text uses "person_name" and the command argument uses the "id" and the command name would be "delete".
like so:
<asp:Repeater ID="rptrSent" runat="server">
<ItemTemplate>
<asp:Button ID="btnDeletePartner" runat="server"
Text='<%# bind("person_name") %>' CommandArgument='<%# bind("id") %>' CommandName="Delete" />
<br />
</ItemTemplate>
</asp:Repeater>

ASP.NET DropDownList bound to data but allows for nulls?

I'm using LINQ to SQL and want to be able to select a parent or no parent. Let's say I have a People table with PersonId, Name and ParentId columns. In ASP I want to enter the name, select a parent and click 'Add' to create a new Person record, but I also want to be able to leave the ParentId null. Don't ask why, this is just a simplified explanation for what I want to do.
<asp:LinqDataSource ID="LinqPeople" runat="server"
ContextTypeName="MyDataContext" EntityTypeName=""
Select="new (PersonId, Name)" TableName="People"/>
<asp:TextBox ID="textName" runat="server" />
<asp:DropDownList runat="server" ID="dropParent"
DataSourceID="LinqPeople" DataTextField="Name" DataValueField="PersonId" />
<asp:Button ID="buttonAddPerson" runat="server" Text="Add" />
Is there any way to display 'None' in the list box with a value of null? I have thought of a few options, which is best or are there any others?
Create a stored procedure for the SQL "SELECT PersonId, Name FROM People UNION SELECT Null, 'NONE'"
Add a CheckBox for "NO PARENT"
Put a ListItem in the markup for the DropDownList
Add the item on the DataBound event handler
I found a better way, adding a ListItem in the markup:
<asp:LinqDataSource ID="LinqPeople" runat="server"
ContextTypeName="MyDataContext" EntityTypeName=""
Select="new (PersonId, Name)" TableName="People"/>
<asp:TextBox ID="textName" runat="server" />
<asp:DropDownList runat="server" ID="dropParent"
DataSourceID="LinqPeople" DataTextField="Name" DataValueField="PersonId">
<asp:ListItem Value="">(none)</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="buttonAddPerson" runat="server" Text="Add" />
I cannot find any way to return the actual value 'NULL' in SelectedValue however, but I can handle that I guess. I think the ListItem way is the best because it is defined in the markup and doesn't require any code...
Don't think you can set the value of NULL since it's a string type.
I don't like the check for NULL, typically, I would use something that doesn't make sense, like -1 or something and check for that. You could also assume that your selected index is 0, however, that could cause problems somewhere else in code if you don't follow throughout the app.

How do I data bind a drop down list in a gridview from a database table using VB?

So in this gridview, there is a column for status and I want to have a drop down list with Pass, Pending, Fail appear when the edit button is clicked. These values are already in a table, so I need to somehow bind from this table to each ddl for every row.
Here is the column from the gridview. As you can see, I would like to just have a label showing when not in edit mode, and a ddl when the edit button is pressed
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="Name"
datatextfield="Name" DataSource="*What goes here?*"> />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text='I don't understand how to get this from the ddl' />
</ItemTemplate>
</asp:TemplateField>
For clarity's sake, my table is named Status, and the database is named DirectImport
There's a few steps to go through here - none of them are particularly difficult, but they can be a bit fiddly (IMHO). The good news is once you've got this working once, it gets easier to do it again!
I'm assuming you've got a <asp:*DataSource> control on your page - my preference is for an ObjectDataSource but I don't think it matters, I think a SqlDataSource works equally well. I've never tried doing this with GridView.DataSource = MyDataSet in code-behind, so I don't know whether that would work or not, but my assumption is that it wouldn't as you wouldn't get the proper two-way binding that you want. This data source feeds your grid with your main data. The key point here is that your database query must return both the Status text field and the Status id.
So your gridview will now look something like:
<asp:objectdatasource runat="server" id="MainDataSource" ... />
<asp:gridview runat="server" id="MyGridView" DataSourceID="MainDataSource">
<Columns>
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text="<%# Bind('Status') %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
The Text="<%# Bind('Status') %>" is the bit you're missing to get the status text into the grid.
Now add a second data source into your markup that reads in the set of values from the Status table.
<asp:objectdatasource runat="server" id="StatusObjectDataSource" ... />
And add the EditItemTemplate into the GridView, which is bound to the Status DataSource.
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="StatusID"
datatextfield="Status" DataSourceID="StatusObjectDataSource"
SelectedValue="<%# Bind('StatusId') %>" />
</EditItemTemplate>
The SelectedValue="<%# Bind('StatusId') %>" is what connects up the two datasets so that when you flip a row into Edit mode, the dropdownlist has the correct item already selected, and when you then save it you've got the Status ID to put into your database.
And you're done.
I have used the RowDataBound event. Here is a small code snippet. HTH
you would have an ItemTemplate in your aspx/ascx
<asp:TemplateField HeaderText="Column Headings">
<ItemTemplate>
<asp:DropDownList ID="ddlName" runat="server" Width="150"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
and in your code behind, you will have
protected void grdDataMap_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlName");
ddl.DataSource = someList;//the source of your dropdown
ddl.DataBind();
}
}
so when you bind your grid with grdDataMap.Databind (assuming your grid id is grdDataMap), row databound event will be called for each row (including header/footer, and thats the reason you check RowType)
so you can probably decide what controls/columns to hide/show/bind inside this row databound event
In the winforms world I pull my objects from the DB into a List(Of Whatever) and use the list as the datasource.
This also lets me add extra "convenience" fields in the object so that I can populate it with stuff from other tables.
I don't know asp.net at all so if you can do something similar, it might help.
A really quick solution is to create a custom web control for the status dropdown. The control will always contain the same data. When it renders you populate the datasource. When it gets added to the gridview, the data will be in the drop down. Hope that helps!

Resources