I have a GridView which has two session vairables used to filter the select statement (TimeStart and TimeFinish). I have a default value for these, which displays the correct information in the GridView.
I have two ASP TextBoxes with TextMode set to Time which I need to update these values. These update the session variables (have set a label's value to check), but do not update the select statement of my GridView.
I've done something Identical for another GridView on the same page, the only difference being that the session variable in an Int32 and being set from a GridView's IndexChanged event, and am confused as to why it's not working for this one.
Source for GridView:
<asp:GridView ID="gvAvailableVets" runat="server" AutoGenerateColumns="False" DataKeyNames="VetID" DataSourceID="AvailableVetsDataSource">
<Columns>
<asp:BoundField DataField="VetID" HeaderText="VetID" ReadOnly="True" SortExpression="VetID" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="MobileNumber" HeaderText="MobileNumber" SortExpression="MobileNumber" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="AvailableVetsDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:VetPracticeConnectionString %>" SelectCommand="SELECT DISTINCT Veternarians.VetID, FirstName, LastName, MobileNumber FROM dbo.Veternarians
INNER JOIN dbo.VetHours
ON Veternarians.VetID = VetHours.VetID
INNER JOIN dbo.Appointments
ON Veternarians.VetID = Appointments.VetID
WHERE #beginTime > VetHours.StartTime
AND #endTime < VetHours.EndTime
AND (#beginTime > Appointments.EndTime
OR #endTime < Appointments.BeginTime) ">
<SelectParameters>
<asp:SessionParameter DefaultValue="9:00" Name="beginTime" SessionField="TimeStart" Type="String" />
<asp:SessionParameter DefaultValue="10:00" Name="endTime" SessionField="TimeFinish" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
C# code behind for the TextBoxes:
protected void txtTimeBegin_TextChanged(object sender, EventArgs e) {
Session["TimeStart"] = txtTimeBegin.Text;
// Used for debugging
lblDebug.Text = Session["TimeStart"].ToString();
}
protected void txtTimeEnd_TextChanged(object sender, EventArgs e) {
Session["TimeFinish"] = txtTimeEnd.Text;
}
Try to rebind your Gridview when any textbox value changed.
protected void txtTimeBegin_TextChanged(object sender, EventArgs e)
{
Session["TimeStart"] = txtTimeBegin.Text;
gvAvailableVets.DataBind();
// Used for debugging
lblDebug.Text = Session["TimeStart"].ToString();
}
protected void txtTimeEnd_TextChanged(object sender, EventArgs e)
{
Session["TimeFinish"] = txtTimeEnd.Text;
gvAvailableVets.DataBind();
}
Related
I'm currently working on an in house project, I've created a GridView connected to a SQL table which looks like this:
GridView1
I created the view content buttons using the following code:
<Columns>
<asp:ButtonField ButtonType="Button" Text="View Content" CommandName="Select" />
<asp:BoundField DataField="ContentID" HeaderText="ContentID" InsertVisible="False" ReadOnly="True" SortExpression="ContentID" />
<asp:BoundField DataField="Code" HeaderText="Code" SortExpression="Code" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:BoundField DataField="URL" HeaderText="URL" Visible="true" SortExpression="URL" />
</Columns>
But this is where I am now stuck. I would like to click on the view content button and have it navigate to the URL on the selected row.
The URL comes from the SQL Table and there is a string so I'd imagine, it would need to be converted first but I could be wrong.
I started to put my code in the following:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewCommandEventArgs x = (GridViewCommandEventArgs)e;
if (x.CommandName == "Select")
{
GridViewRow row = GridView1.SelectedRow;
}
}
Add your code in GridView1_RowCommand event of gridview:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow row = (GridViewRow)(((BoundField)e.CommandSource).NamingContainer);
int index = row.RowIndex;
string url = (GridView1.Rows[index].FindControl("URL") as BoundField).Text;
Response.Redirect(url); // url can be from your sql table
}
}
Note: Don't forget to add OnRowCommand event in GrindView <asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand" >
GridViewRow row = (GridViewRow)(((BoundField)e.CommandSource).NamingContainer);
int index = row.RowIndex;
string url = (GridView1.Rows[index].FindControl("URL") as BoundField).Text;
Response.Redirect(url); // url can be from your sql table
So i made the change. Unfortunately, BoundField does not contain a definition for NamingContainer.
Also, GridView1.Rows[index].FindControl("URL") as BoundField fails due to the following error, cannot convert type 'system.web.ui.control' to 'system.web.ui.webcontrols.boundfield' via a reference conversion, boxing conversion, unboxing conversion or null type conversion.
I have an ObjectDataSource
<asp:ObjectDataSource SelectCountMethod="GetCount" EnablePaging="true" SortParameterName="sortExpression" ID="customersDS" runat="server" SelectMethod="GetList" TypeName="expenses.Classes.ExpenseFactory" DeleteMethod="Delete" UpdateMethod="Update" >
<SelectParameters>
<asp:ControlParameter ControlID="IdHidden" PropertyName="Value" Name="userId" />
<asp:Parameter DbType='Boolean' DefaultValue='false' Name='isExpense' />
<asp:Parameter DbType='Boolean' DefaultValue='false' Name='containRepeated' />
<asp:ControlParameter DbType="Int32" DefaultValue="" ControlID="CategorySelector2" Name="categoryId" />
<asp:ControlParameter DbType="DateTime" DefaultValue="" ControlID="FromSpentDateCalendarBox" Name="from" />
<asp:ControlParameter DbType="DateTime" DefaultValue="" ControlID="ToSpentDateCalendarBox" Name="to" />
</SelectParameters>
<UpdateParameters>
<asp:ControlParameter ControlID="IdHidden" PropertyName="Value" Name="userId" />
<asp:Parameter DbType='Boolean' DefaultValue='false' Name='isExpense' />
</UpdateParameters>
</asp:ObjectDataSource>
connected to a GridView
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
AllowPaging="True" AllowSorting="True"
DataSourceID="customersDS" CssClass="gtable sortable width100" DataKeyNames="Id"
AlternatingRowStyle-CssClass="odd" CellPadding="0" GridLines="None" OnPreRender="PreRender"
OnRowDataBound="GridView1_RowDataBound"
>
with edit and delete buttons in a CommandField
<asp:CommandField ItemStyle-Width="75px" HeaderStyle-Font-Bold=true HeaderText="<%$ Resources:Default, Actions %>" EditImageUrl="~/img/edit.png" ButtonType='Image' ShowEditButton="True" UpdateImageUrl="~/img/save.gif" CancelImageUrl="~/img/cancel.png" >
<ControlStyle CssClass="my_edit_buttons" />
</asp:CommandField>
Everything is located inside and UpdatePanel. The GridView and ObjectDataSource support and use paging. Paging works without any problems. The problem is editing. When I click edit on the first page, everything works as expected. When I click edit on the n-th item on the second or other page (greater than one), the GridView switches to the first page and selected the n-th item for editing.
(More concerete example: I switch to the second page, I select the item number 2 on that page to be edited, the GridView switches to the first page and selects the item number 2 (on the first page) to be edited).
Any ideas what may be the problem?
EDIT:
PreRender (setting GridView header):
protected void PreRender(object sender, EventArgs e)
{
try
{
GridView1.UseAccessibleHeader = false;
GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;
}
catch
{
}
}
RowDataBound (changind delete button to a custom one with configmation prompt|:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// we are using a html anchor and a hidden asp:button for the delete
HtmlAnchor linkDelete = (HtmlAnchor) e.Row.FindControl("linkDelete");
ImageButton btnDelete = (ImageButton) e.Row.FindControl("btnDelete");
string prompt = Resources.Default.DeletePrompt;
linkDelete.Attributes["onclick"] = string.Format(prompt, btnDelete.ClientID);
Expense expense = e.Row.DataItem as Expense;
if (expense!=null)
{
if (expense.SpentDate>DateTime.Now)
{
e.Row.CssClass = "future";
}
}
e.Row.Cells[1].CssClass = e.Row.Cells[4].CssClass = "red";
}
Hey people I'm having a little issue regarding a transfer of variables from Site.Master to another window, the purpose is to make a search function accessed from the whole asp.net web application...
The code which is relevant from Site.Master:
<div class="search">
<asp:Label ID="LandID" runat="server" Text="LandID"/>
<asp:TextBox ID="txtSearch" runat="server" />
<asp:Label ID="CarBrand" runat="server" Text="CarBrand" />
<asp:TextBox ID="txtSearch2" runat="server" />
<asp:Label ID="Model" runat="server" Text="Model"/>
<asp:TextBox ID="txtSearch3" runat="server" />
<asp:Button ID="cmdSearch" runat="server" Text="Search" Style="width: 100px" OnClick="cmdSearch_Click" />
</div>
The Code from Site.Master.Cs:
public static string Text { get; set; }
public static string Text2 { get; set; }
public static string Text3 { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
}
protected void cmdSearch_Click(object sender, EventArgs e)
{
Text = txtSearch.Text;
Text2 = txtSearch2.Text;
Text3 = txtSearch3.Text;
Response.Redirect("search.aspx");
}
The code from the search.aspx:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged" DataKeyNames="ID">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" InsertVisible="False"
ReadOnly="True" />
<asp:BoundField DataField="LandID" HeaderText="LandID" SortExpression="LandID" />
<asp:BoundField DataField="Bilmaerk" HeaderText="Bilmaerk" SortExpression="Bilmaerk" />
<asp:BoundField DataField="Model" HeaderText="Model" SortExpression="Model" />
<asp:BoundField DataField="Variant" HeaderText="Variant" SortExpression="Variant" />
<asp:BoundField DataField="StartYear" HeaderText="StartYear" SortExpression="StartYear" />
<asp:BoundField DataField="SlutYear" HeaderText="SlutYear" SortExpression="SlutYear" />
<asp:BoundField DataField="Volumen" HeaderText="Volumen" SortExpression="Volumen" />
<asp:BoundField DataField="MaxDrej" HeaderText="MaxDrej" SortExpression="MaxDrej" />
<asp:BoundField DataField="AntalCylindre" HeaderText="AntalCylindre" SortExpression="AntalCylindre" />
<asp:BoundField DataField="TopHast" HeaderText="TopHast" SortExpression="TopHast" />
<asp:BoundField DataField="Acceleration" HeaderText="Acceleration" SortExpression="Acceleration" />
<asp:BoundField DataField="Beskrivelse" HeaderText="Beskrivelse" SortExpression="Beskrivelse" />
<asp:BoundField DataField="Effekt" HeaderText="Effekt" SortExpression="Effekt" />
<asp:BoundField DataField="Picture" HeaderText="Picture" SortExpression="Picture" />
</Columns>
</asp:GridView>
<selectparameters>
<asp:ControlParameter ControlID="<%=Text1 %>"></asp:ControlParameter>
<asp:ControlParameter ControlID="<%=Text2 %>"></asp:ControlParameter>
<asp:ControlParameter ControlID="<%=Text3 %>"></asp:ControlParameter>
</selectparameters>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:CarConnectionString %>"
SelectCommand="SELECT * FROM [Bil] WHERE (([LandID] LIKE '%' +#LandID+ '%') AND ([Bilmaerk] LIKE '%' +#Bilmaerk+ '%') AND ([Model] LIKE '%' +#Model+ '%'))">
<SelectParameters>
<asp:ControlParameter ControlID="Text1" Name="LandID" PropertyName="Text" Type="String"
DefaultValue="%" />
<asp:ControlParameter ControlID="Text2" Name="Bilmaerk" PropertyName="Text" Type="String"
DefaultValue="%" />
<asp:ControlParameter ControlID="Text3" Name="Model" PropertyName="Text" Type="String"
DefaultValue="%" />
</SelectParameters>
</asp:SqlDataSource>
the Relevant code from search.aspx.cs:
public partial class search : System.Web.UI.Page
{
protected string Text1 { get; set; }
protected string Text2 { get; set; }
protected string Text3 { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
Text1 = SiteMaster.Text;
Text2 = SiteMaster.Text2;
Text3 = SiteMaster.Text3;
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
Constructor.SelectedCar = GridView1.SelectedRow.Cells[1].Text;
Response.Redirect("Selected.aspx");
}
}
On page load or page prerender of the master based on the life cycle of your page, initially store the values the textboxes of different search fields into the session variables respectively.
And then you can access these variables on search button click then you can proceed further of the basic steps like going to database and search the relevant fields and so on.
By using these session variables you can access them anywhere in any page untill and unless you change the values....
public void search(object sender ,EventArgs e)
{
string Search = session["search"].toString();
Search = Search + "%";
SqlDataSource1.SelectParameters.Clear();
SqlDataSource1.SelectParameters.Add("search", Search);
Search = "%" + Search;//for user name ,user email,languages made the search criteria as anywhere in the word for others it is starting letter
SqlDataSource1.SelectParameters.Clear();//again we have to clear and add since search is changed
SqlDataSource1.SelectParameters.Add("search", Search);
SqlDataSource1.SelectCommand = "SELECT [UserID], [UserName], [UserEmail], [UserContact], [UserAddress], [Gender], [Languages], [Status], [Passwords],[Image] FROM [Users_raghu] where [UserName] like #search";
}
This is the sample you can refer here I have given you only one search variable in your case you have to take 3 session variables and proceed further
Hope this helps :D
why dont you use session to transfer data from one page to another..??
its quite simple ,
//this is how you will create the Session on master page
{
Session["text"] = txtearch.Text;
Session["Text2"] = txtSearch2.Text;
Session["Text3"] = txtSearch3.Text;
}
on another page just use it like
{
string a = Session["text"].ToString();
string b = Session["text2"].ToString();
string c = Session["text3"].ToString();
}
Try use HTTP GET method like code bellow:
On your Site.Master.Cs
protected void cmdSearch_Click(object sender, EventArgs e)
{
Text = txtSearch.Text;
Text2 = txtSearch2.Text;
Text3 = txtSearch3.Text;
Response.Redirect(string.Format("search.aspx?txtSearch={0}&txtSearch2={1}&txtSearch3={2}", Text, Text2, Tex3));
}
On your search.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
Text1 = Request["txtSearch"];
Text2 = Request["txtSearch2"];
Text3 = Request["txtSearch3"];
}
Also you can add GET parameter to your master page control by call:
(Master.FindControl("txtSearch") as TextBox).Text = Request["txtSearch"];
I have a problem with my delete parameter. I am using a GridView and a ObjectDataSource.
And I would like to delete one row. But when I debug is see that the value of CustomerId is always 0 in my Business Logic Layer.
Here is my code
I have two delete parameters, Id and CustomerId. These are the same names as the ones in my BLL.
<asp:GridView DataKeyNames="Id" ID="gvFavoriteMovies" DataSourceID="odsFavoriteMovies" AutoGenerateColumns="False"
runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblTitel" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Title")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="odsFavoriteFilm" runat="server"
TypeName="MovieMonstrDataLayer.bll.BLLMovies"
SelectMethod="GetFavoriteMoviesFromUser"
DeleteMethod="DeleteFavoriteMoviesFromUser"
onobjectcreating="odsFavoriteFilm_ObjectCreating"
ondeleting="odsFavoriteFilm_Deleting">
<DeleteParameters>
<asp:Parameter Name="Id" DbType="Int32" Direction="Input" />
<asp:Parameter Name="CustomerId" DbType="Int32" Direction="Input" />
</DeleteParameters>
<SelectParameters>
<asp:Parameter DbType="Int32" Direction="Input" Name="CustomerId" />
</SelectParameters>
</asp:ObjectDataSource>
This is in the the code behind file
When deleting a row, I assign the value of the logged in Customer to the Delete Parameter CustomerId. This all works. I give the right value to the delete parameter.
protected void odsFavoriteFilm_Deleting(object sender, ObjectDataSourceMethodEventArgs e)
{
if (Context.User.Identity.IsAuthenticated)
{
this.odsFavoriteFilm.DeleteParameters["CustomerId"].DefaultValue = ((MovieMonstrIdentity)Context.User.Identity).Customer.Id.ToString();
this.odsFavoriteFilm.DataBind();
}
}
Normally in my Business Logic Layer, I should get now the right CustomerId, but I always get 0. While no Costumer has that ID.
public int DeleteFavoriteFilmFromUser(int Id, int CustomerId)
{
try
{
return Adapter.DeleteFavoriteFilmFromUser(Id, CustomerId);
}
catch (Exception ex)
{
throw ex;
}
}
What am I doing wrong?
Include CustomerID in your DataKeyNames
<asp:GridView DataKeyNames="Id,CustomerId" ...>
Either do this before the updating
protected odsFavoriteFilm_DataBinding(object sender, EventArgs e) {
if(!IsPostBack) {
this.odsFavoriteFilm.DeleteParameters["CustomerId"].DefaultValue = ((MovieMonstrIdentity)Context.User.Identity).Customer.Id.ToString();
}
}
or set the actual parameter value for the command
protected void odsFavoriteFilm_Deleting(object sender, ObjectDataSourceMethodEventArgs e) {
if (Context.User.Identity.IsAuthenticated) {
e.Command.Parameters["CustomerId"].Value = ((MovieMonstrIdentity)Context.User.Identity).Customer.Id.ToString();
}
}
Recent problems I've had are making me question my whole philosophy and assumptions regarding GridViews.
Currently, I have used something along the lines of the following model.
In Markup:
<asp:UpdatePanel ID="pnlSearch" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtSearch" runat="server"
ontextchanged="txtSearch_TextChanged"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="pnlGridView" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" EnableViewState="false" AllowPaging="true" PageSize="20" DataSourceID="MyDataSource" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="COL_1" HeaderText="Happy Data" SortExpression="COL_1" />
<asp:BoundField DataField="COL_2" HeaderText="Happy Related Data" SortExpression="COL_2" DataFormatString="{0:M/dd/yyyy}" />
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="txtSearch" EventName="TextChanged" />
</Triggers>
</asp:UpdatePanel>
<asp:SqlDataSource ID="MyDataSource" runat="server"></asp:SqlDataSource>
Pretty basic stuff. A GridView. A data source. A text box for searching results. I include the UpdatePanels only because I'm somewhat convinced they could be part of my problems.
Over in my code behind, I usually would do something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyDataSource.ConnectionString = ConfigurationManager.ConnectionStrings["OracleConnectionString"].ConnectionString;
MyDataSource.ProviderName = ConfigurationManager.ConnectionStrings["OracleConnectionString"].ProviderName;
GridView1.EmptyDataText = "No comments found.";
PopulateGridView();
}
}
protected void PopulateGridView()
{
string strQuery = #"SELECT COL_1,
COL_2
FROM some_table
WHERE COL_3 = :important_filter";
MyDataSource.SelectCommand = strQuery;
MyDataSource.SelectParameters.Clear();
MyDataSource.SelectParameters.Add(":important_filter", Request.QueryString["filter"]);
GridView1.DataBind();
GridView1.PageIndex = 0;
}
protected void txtSearch_TextChanged(object sender, EventArgs e)
{
string strQuery = #"SELECT COL_1,
COL_2
FROM some_table
WHERE COL_3 = :important_filter AND lower(COL_2) LIKE :search";
MyDataSource.SelectCommand = strQuery;
MyDataSource.SelectParameters.Clear();
MyDataSource.SelectParameters.Add(":important_filter", Request.QueryString["filter"]);
MyDataSource.SelectParameters.Add(":search", "%" + txtSearch.Text.Trim().ToLower() + "%");
GridView1.DataBind();
GridView1.PageIndex = 0;
}
Nothing too fancy. I initially connect up the data source to a connection string from the config file (as is necessary in a multi instance environment), wire up the query and databind. On searches, I change the query and rebind.
The only problem?
The above doesn't work. Why? The data source loses it's query, connection string, provider name, etc on post back. So the gridview commits suicide. The same thing happens when I try to change pages...either on initial load or with a search populated.
I "solved" this problem last week by manually adding the datasource to control state and repopulating the values from control state, but that seems hackish.
What am I not understanding?
You have the update mode set to conditional so you need to call update on 'pnlGridView'
GridView1.DataBind();
GridView1.PageIndex = 0;
pnlGridView.Update();
I would also revist how you are using your DataSource
<asp:SqlDataSource ID="ProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:OracleConnectionString %>"
SelectCommand="SELECT COL_1, COL_2 FROM some_table WHERE COL_3 = #important_filter">
<SelectParameters>
<asp:ControlParameter ControlID="textBox?not sure where this is coming from" PropertyName="SelectedValue" Name="important_filter" Type="string" DefaultValue="" />
</SelectParameters>
</asp:SqlDataSource>
You could also use a server side event handler and set the important filter manually.
protected void SQLDataSource_Selecting(object sender, SQLDataSourceSelectingEventArgs e) {
e.InputParameters["important_filter"] = "whatever";
}
And add the event to your markup for your SQLDataSource.
<asp:SqlDataSource ID="MyDataSource" runat="server" OnSelecting="SQLDataSource_Selecting" />