How to sort items that are databound - c#

I have a problem that has been a thorn in my side for nearly a week. I have a site that users can create an account and load videos of there choosing from a database. I would like the videos to show up in a certain order on there page when they look at the ones they selected. My problem is that the videos show up in a random order. I know this may be basic but I am just now entry level (has only been two weeks since I graduated). All the functionality works, so no help needed there, just this darn order thing.
Specs:
Coded in C# ASP.NET
They add and delete selections via checkbox list.
I have the items databound so I can add and remove videos on the back end.
I know this may get me some minus votes, and though I would prefer it not, I just need some help with this issue to be done with the whole project. Before you yell at me for not having code, please tell me what you would like to see so I don't add tons of useless code.
I am not trying to me short, rather I am frustrated that everything I tried won't work.
Thank you in advance.
EDIT:
Here is the SqlDataSource for it:
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:fivideoConnectionString %>"
ProviderName="<%$ ConnectionStrings:fivideoConnectionString.ProviderName %>"
InsertCommand="INSERT INTO dealervideo(DealerRecID,VideoRecID) VALUES (?,?)"
DeleteCommand="DELETE FROM dealervideo where RecID = ?" >
<DeleteParameters>
<asp:SessionParameter Name="recid" SessionField="videorecid" />
</DeleteParameters>
<InsertParameters>
<asp:ControlParameter ControlID="hidRecID" Name="recid" PropertyName="Value" />
<asp:SessionParameter Name="videorecid" SessionField="videorecid" />
</InsertParameters>
</asp:SqlDataSource>
And here is the Gridview:
<asp:GridView ID="GridView2" runat="server"
DataSourceID="SqlDataSource2" AutoGenerateColumns="False"
DataKeyNames="RecID" CellSpacing="5" BorderStyle="None" BorderWidth="0px">
<Columns>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:CheckBox ID="cbDelete" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
</Columns>
</asp:GridView>
And this is the event when they click to add a video to the list:
protected void btnAddVideo_Click(object sender, EventArgs e)
{
foreach (GridViewRow gvr in GridView3.Rows)
{
CheckBox chkItem = (CheckBox)gvr.FindControl("cbAdd");
if (chkItem.Checked)
{
String sRecID = GridView3.DataKeys[gvr.RowIndex].Value.ToString();
Session["videorecid"] = sRecID;
SqlDataSource2.Insert();
SqlDataSource2.SelectCommand = "SELECT * FROM dealervideo inner join videos on videos.RecID = dealervideo.VideoRecID inner join dealers on dealers.RecID = dealervideo.DealerRecID where dealers.RecID = " + hidRecID.Value;
}
}
GridView2.DataBind();

Add an "ORDER BY" to your Select Command and the field which you want it to be ordered on.
Example:
SqlDataSource2.SelectCommand = "SELECT * FROM dealervideo inner join videos on videos.RecID = dealervideo.VideoRecID inner join dealers on dealers.RecID = dealervideo.DealerRecID where dealers.RecID = " + hidRecID.Value + " ORDER BY videos.RecID";

I assume you are binding to the results of a stored procedure or sql command? In that case, why not use an "Order By" clause in your SQL statement? The items will be displayed in the order in which they are pulled from the database.

Related

Gridview's (populated by SqlDataSource) Update is not updating, don't know how to trace

I'm still a newbie in ASP.NET, and right now, my Gridview is not "updating" when I hit "Update". Here is how I have my GridView w/ the SqlDataSource :
<asp:GridView ID="ProjectTable" runat="server" AutoGenerateColumns="False" AutoGenerateEditButton="True" DataSourceID="PopulateProjectTable" DataKeyNames="ProjectID">
<Columns>
<asp:BoundField DataField="ProjectID" HeaderText="Project ID" ReadOnly="True" SortExpression="ProjectID" />
<asp:BoundField DataField="ProjectDescription" HeaderText="Project Description" ReadOnly="True" SortExpression="ProjectDescription" />
<asp:BoundField DataField="ProjectNotes" HeaderText="Project Notes" SortExpression="ProjectNotes" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="PopulateProjectTable" runat="server" ConnectionString="<%$ ConnectionStrings:sandboxConnectionString %>" SelectCommand="SELECT * FROM [Projects]" UpdateCommand="UPDATE [Projects] SET ProjectNotes = #project_notes">
<UpdateParameters>
<asp:Parameter Name="project_notes" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
I have no code in the code behind. When I hit "Edit", the third column is suppose to be "editable". When I hit "Update", the page does a postback but what was entered in the third column does not persist and is instead lost. What is going on?
In addition, how would I trace this issue? This is so in the future, I can see what the SQL string is. Thank you.
EDIT: Turns out to be a typo that caused my issue. Problem solved!
Is the spelling correct on the ProjectNotes DataField? The problem you are describing sounds like the field is not bound properly.
I would run SQL profiler while hitting the update. To see what exactly was being sent back to the Database.
You should see your parameter as well. Set the filter to the DB your looking at if you have multiple and give it a try and realtime run the same test by hitting the update button again.
Please modify your update command from this
UpdateCommand="UPDATE [Projects] SET ProjectNotes = #project_notes"
to this
UpdateCommand="UPDATE [Projects] SET ProjectNotes = #project_notes" WHERE ProjectID=#ProjectID
Please add to your DataSource
OnUpdated="OnDSUpdatedHandler">
and add the following method
<script runat="server">
private void OnDSUpdatedHandler(Object source, SqlDataSourceStatusEventArgs e) {
var dbg = e;
}
</script>
Set breakpoint on line
var dbg = e;
and examine what is being in that variable. The answer should be there

ASP Dropdown list not changing the value

First off, I'm still getting my web dev legs under me. I've combed through piles of SO posts, blogs, newsgroups and articles and I cannot seem to fix my problem. It's very similar to at least 10 different posts I've looked at.
I have an ASP gridview, which acts as a display and a select column. When you click select it throws the data into a detailsview. I have one field that needs to be a drop down box, but whenever I change the value and click update the value that is sent to the command is the original value.
Page Markup:
<asp:TemplateField HeaderText="Planner Name">
<ItemTemplate>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="cboCurrentPlanner" runat="server" DataSourceID="plannerDataSource"
DataTextField="planner_name" DataValueField="planner_id" SelectedValue='<%# Eval("planner_id") %>' AutoPostBack="true" ></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Fields>
<FooterStyle BackColor="#CCCC99" ForeColor="Black" />
<HeaderStyle BackColor="#333333" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" />
</asp:DetailsView>
sqlDataSource:
SelectCommand="SELECT vendor_key, vendor, planner_name, street, city, state_country, planner_id, country FROM V_MAP_MarkerInfo WHERE (vendor_key = #vendor_key)"
UpdateCommand="MAP_usp_webUpdatePlanToVendor"
UpdateCommandType="StoredProcedure" onupdating="mapDetailSource_Updating" >
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" Name="vendor_key"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="vendor_key" Type="String" />
<asp:Parameter Name="planner_id" Type="Int32" />
<asp:Parameter Name = "vendor" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="plannerDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:vendor_mapConnectionString %>"
SelectCommand="SELECT [planner_id], [planner_name] FROM [MAP_planners]"
OldValuesParameterFormatString="original_{0}">
</asp:SqlDataSource>
I won't post the stored procedure code, I know that is working. The original value is the only value that makes it to the parameter.
I've tried all sorts of combinations of <%# Bind/Eval() %> postbacks but I can't find the right combination.
When I click select, I want the current planner to be selected in the dropdown list. When I select a new planner and click update I would like the planner to update. I'm not sure why this is so difficult or what I have royally screwed up to make it difficult but I am at my wits end. If at all possible, I would like an explanation of what is going on and not just the magical line of code that makes it work.
Flabbergasted is an understatement.
EDITS: ViewStateEnbabled="true" added to dropdownlist, the selectedIndexChanged event is firing.
EDIT AGAIN: Changed the planner_id to <asp:ControlParameter> added monitors to DetailsView1_OnDataBind and MapDataSource1_updating and the value is all over the place. but I can't see where it's being reset.
Do you have EnableViewState="false" set on the #Control or #Page settings? If viewstate is not enabled the control will always have the default value as the selected value. This can be set at the aspx level or the ascx level.
http://msdn.microsoft.com/en-us/library/ms972976.aspx
So I am a complete idiot, the DetailsView DataKeyNames property was not set correctly. I had accidentally added "planner_id" as a key from the wizard.
The code was fine all along. Thank you to everyone for trying, but I am a lost cause!

How to add multiple paramaters to a SQL select query using a checkboxlist?

I'm hoping to retrieve data-rows from a database using a query with a checkboxlist as a control parameter. The problem is multiple selected values on the checkboxlist only return one value as seen here...
Illustration
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatDirection="Horizontal" DataSourceID="SqlDataSource1" DataTextField="Fruit" DataValueField="Fruit" ></asp:CheckBoxList>
<asp:SqlDataSource runat="server" ID="SqlDataSource1" ConnectionString='<%$ ConnectionStrings:f-StopConnectionString %>' SelectCommand="SELECT [Fruit] FROM [Table_1]"></asp:SqlDataSource>
<br />
<asp:Button ID="Button1" runat="server" Text="Select" OnClick="Button1_Click" />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource4">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID"></asp:BoundField>
<asp:BoundField DataField="Fruit" HeaderText="Fruit" SortExpression="Fruit"></asp:BoundField>
</Columns>
</asp:GridView>
<asp:SqlDataSource runat="server" ID="SqlDataSource4" ConnectionString='<%$ ConnectionStrings:f-StopConnectionString %>'
SelectCommand="SELECT * FROM [Table_1] WHERE ([Fruit] LIKE '%' + #Fruit + '%')">
<SelectParameters>
<asp:ControlParameter ControlID="CheckBoxList1" PropertyName="SelectedValue" Name="Fruit" Type="String"></asp:ControlParameter>
</SelectParameters>
</asp:SqlDataSource>
Is there a way to pass multiple selections so that the query would read:
(WHERE [Fruit] LIKE '%'Apples'%') OR (WHERE [Fruit] LIKE '%'Oranges'%')
Any help at all would be greatly appreciated.
As far as I understand, as you have provided no code, you want to use linq (or entity framework) to query database.
You need then to build lambda expression depending on user selection and pass it to your query.
See Lambda expressions trees here for start:
http://www.codeproject.com/Articles/17575/Lambda-Expressions-and-Expression-Trees-An-Introdu
This can help also:
Can I use custom delegate method in Where method of Entity Framework?
If you want just to pass sql select command string, then you should build custom where clause depending on user selection.

ASP.NET 2.0 with conditional radio button in a GridView

I'm looking to have a GridView displaying "Events" from a database, and then in the last column I want to do another database lookup (for each row) to see if that event is full or not.
If it's not full, display a radio button. If it is full display text "Full".
I think this is best done with OnRowDataBound event but could use a little help.
I can see how to change an asp label text but not display a radio button.
register.aspx:
<asp:GridView ID="GridView2" runat="server" DataSourceID="SqlDataSource2" AutoGenerateColumns=false CellPadding="5" HeaderStyle-BackColor="DarkGray" Width="450px" OnRowDataBound="GridView2_OnRowDataBound">
<Columns>
<asp:BoundField DataField="sessionDate" HeaderText="Date" DataFormatString="{0:D}" />
<asp:BoundField DataField="sessionTime" HeaderText="Time" />
<asp:BoundField DataField="site" HeaderText="Site" />
<asp:BoundField DataField="room" HeaderText="Room" DataFormatString="{0:D}" />
<asp:TemplateField HeaderText="">
<ItemTemplate>
<input type="radio" name="rdoSessionID" value='<%# Eval("ses_ID") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#99CCFF" />
</asp:GridView>
<br />
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:sqlConnection2 %>"
SelectCommand="SELECT * FROM dbo.sessions WHERE site LIKE #ses_site AND sessionDate = #ses_date ORDER BY sessionDate">
<SelectParameters>
<asp:SessionParameter name="ses_site" SessionField="ses_site" Type="String" />
<asp:SessionParameter name="ses_date" SessionField="ses_date" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
There are a few ways you can do this.
You can do this on the OnRowDataBound , If the Item you're dealing with is a DataItem, grab the value you need from the current row, and do a quick DB Lookup
When you get your resultset back from the database, do another lookup on each event. This way when your data leaves your data layer / methods you already have everything you need.
Modify your SQL query to return this information with the list of events. You already know the Events, you could just have a sub query to query to see if it's full or not (or the # of people registered, and the Max # allowed so you can show that). This way you only have to do 1 hit against the database and it will save you a bunch of processing. (My favorite)
You would still need to overload the OnRowDataBound event for all 3 of those solutions. You'd hide the radio button if it was full, and ensure it was visible if the event was not full. The difference is where do you get your data.
Do you want to do:
1 Good hit (list of events)
X amounts of small hits for each event
or
1 Good hit for list of events + if each event is full or not.
If you want to entertain #3, post your SQL Query and we can go from there.
Quick example of the OnRowDataBound event.
protected void MyGridView_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox cbox = (CheckBox)e.Row.FindControl("chkBox");
// Do some funky logic
cbox.Visible = Event.HasRoom; //Boolean Propery
// Or
cbox.Visible = Convert.ToBoolean(DataBinder.Eval(e.Row.DataItem, "HasRoom").ToString());
}
}
Update 1:
For your GridView, You can use
<ItemTemplate>
<asp:CheckBox runat="server" ID="Checkbox1" ToolTip=" Sign up For event " text="Event stuff" />
</ItemTemplate>
If you want to use a template, don't use a regular control, use a control.
For the query you could do the following. I'm not 100% sure on your table structure so I did it the way I normally would:
Table: Session (sess_id(PK), SessionDate, SessionTime, Site, Room)
Table: Registrants (RegistrantID (PK), sess_id (FK to Session), UserID (FK to users that are registered)
SELECT SessionDate, SessionTime, Site, Room, ses_ID,
(SELECT Count(ses_ID) FROM Registrants R WHERE R.Ses_ID= S.ses_Id) as [Registrants]
FROM dbo.Sessions s
Use the OnRowDataBound event, like this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
RadioButton radio = e.Row.FindControl("RadioButton1") as RadioButton;
if (radio != null)
{
radio.Visible = SomeCheckThatReturnsBoolean((int)GridView1.DataKeys[e.Row.RowIndex]["SomeID"]);
}
}
If possible though, you should return the data with the GridView results, and store the value in a data key, so you can do something like this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
RadioButton radio = e.Row.FindControl("RadioButton1") as RadioButton;
if (radio != null)
{
radio.Visible = (bool)GridView1.DataKeys[e.Row.RowIndex]["SomeBooleanValue"];
}
}
EDIT: Based on your comment to #Ryan, I think you should be able to include that flag in your query. I don't know your database at all, but you can try using a derived table or subquery to get the registrant session counts. Here's a rough example to work off of:
SELECT ID,
ISNULL(Registrants.RegistrantCount, 0) RegistrantCount
...
FROM Table1 t1
LEFT OUTER JOIN (
SELECT ForeignKeyID,
COUNT(RegistrantID) RegistrantCount
FROM Registrants
GROUP BY ForeignKeyID
) Registrants
ON Registrants.ForeignKeyID = t1.ID

ASP. NET C# GridView Paging

Hi good day to all. I have this web application for a certain company. In this web application there is a part that uses GridView to display records from the database and the way it is being displayed it is hard coded. I'll display my codes bellow.
string SQLCommand = "SELECT LastName +', ' +FirstName + ' '+MiddleInitial AS 'Name', UserName + ' 'As 'User Name', StreetAddress FROM CustomersMaster Where LastName Like '%"+ SearchText.Text.Trim() + "%'";
SqlCommand com = new SqlCommand(SQLCommand, con);
SqlDataAdapter adp = new SqlDataAdapter(com);
DataTable tbl = new DataTable();
adp.Fill(tbl);
AdminViewBuyersGV.DataSource = tbl;
AdminViewBuyersGV.DataBind();
My problem is I want to use the "Paging" property of the GridView but when I activated the "Paging" property and then when I run it there's an error that says that "The data source does not support server-side data paging". I just want to know how to use paging when I already hard-coded it.
Is there a way on how to solve my problem. Thank You in Advance and God Bless! :)
Make sure you are acting on data...
if (tbl.Rows.Count > 0)
{
AdminViewBuyersGV.DataSource = tbl;
AdminViewBuyersGV.DataBind();
}
else
{
// no records
}
did you write code for the AdminViewBuyersGV_PageIndexChanging routine?
Unless you have a good reason for binding your datasource in code, you might want to look at using a SqlDataSource control in the .aspx page. You can give it a parameter (which is safer than building a sql string the way you are) and it should support paging out of the box...
Ok, so full example using SqlDataSource (as Kendrick mentioned):
First you need to collect the parameters from your query, which it looks like you are already doing in a textbox somewhere. Something like this:
<asp:Label ID="lblLastName" runat="server" AssociatedControlID="tbLastName" Text="Last Name" ClientIDMode="Static" />
<asp:TextBox ID="tbLastName" runat="server" ClientIDMode="Static" />
<asp:Button ID="btnSearch" runat="server" ClientIDMode="Static" Text="Search" />
Now we need to take your Raw Inline SQL out of the code behind and move it into a SqlDataSource. We also want to get rid of the potential SQL Injection you have in your query by using a parameterized query instead :) In order to do that we need to hook up our TextBox to the parameter, but luckily DataSource controls allow us to do this without any code by using SelectParameters.
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ContactManagerConnectionString %>"
SelectCommand="SELECT LastName + ', ' + FirstName + ' ' + MiddleInitial AS 'Name', UserName AS 'User Name', StreetAddress FROM CustomersMaster WHERE (LastName LIKE '%' + #SearchText + '%')">
<SelectParameters>
<asp:ControlParameter ControlID="tbLastName" ConvertEmptyStringToNull="true"
Name="SearchText" PropertyName="Text" DbType="String" />
</SelectParameters>
</asp:SqlDataSource>
Once those two pieces are in place it is just a matter of setting up your grid the way you want, and setting the AllowPaging property to true.
<asp:GridView runat="server" AllowPaging="True" DataSourceID="SqlDataSource1"
AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" ReadOnly="True"
SortExpression="Name" />
<asp:BoundField DataField="User Name" HeaderText="User Name"
SortExpression="User Name" />
<asp:BoundField DataField="StreetAddress" HeaderText="StreetAddress"
SortExpression="StreetAddress" />
</Columns>
</asp:GridView>
VOILA!
Codeless paging*
* It is worth noting that this is pretty poor in terms of optimization as all the paging work is done on the Web Server. To really make this efficient you would want to employ some paging at the database level. Otherwise you will bring back every record every single time.
It says it doesn't like the data you are binding. So try to tidy the data you are binding:
AdminViewBuyersGV.DataSource = tbl.ToList();

Categories