Asp.net grid view bind to dynamic select query - c#

I want to pass the sql select query from the code behind and based on that query, data should be automatically fill in the grid view. The select query will be different i.e. it can select any tables or views. My code is as follows.
CodeBehind
Protected void ExecuteButton_Click(object sender, EventArgs e)
{
string sql = SqlQueryTextBox.Text;
SqlDataSource1.SelectCommand = sql;
GridView1.Databind();
}
Asp Markup
<asp:GridView ID="GridView1" runat="server"
DataSourceID="SqlDataSource1" AutoGenerateColumns="true">
</asp:GridView>
But nothing is loaded in grid view. Upto now I have used grid view only to bind single table and its columns. Is there any mistake in my logic? How can I fill the grid with dynamic data?

This works fine for me...
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="Data Source=*******Initial Catalog=*******;Persist Security Info=True;User ID=*******;Password=*******" ></asp:SqlDataSource>
<div>
<asp:TextBox ID="SqlQueryTextBox" runat="server" ></asp:TextBox>
<asp:Button ID="ExecuteButton" OnClick="ExecuteButton_Click" runat="server" Text="Execute"/>
</div>
<div>
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" AutoGenerateColumns="true" />
</div>
..
protected void ExecuteButton_Click(object sender, EventArgs e)
{
SqlDataSource1.SelectCommand = SqlQueryTextBox.Text;
GridView1.DataBind();
}
Ps. I used "SELECT * FROM information_schema.tables" as my select statement
I think you need to check your connection string. and then get back to us.

string sql = SqlQry.Text;
SqlDataSource1.SelectCommand = sql;
SqlDataSource1 .Select (DataSourceSelectArguments .Empty );
Gv_1.DataBind();

Related

Asp.Net C# Delete row from dataTable gridview on button click

I'm displaying a datatable that selects a number of elements from the database (IncomingsId, Type, Cost, Frequency) and I'm not sure how to delete a row when a button is clicked.
I've tried many solutions so far but nothing is working.
Here is the button I have within my Grid view
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:button id="DeleteRowButton" text="Delete Record" onclick="DeleteRowButton_Click" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
And here is the code behind this page were I am creating the datatable.
SqlConnection con;
public _Default()
{
con = new SqlConnection(#"MySQLConnection");
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DisplayRecord();
}
}
public DataTable DisplayRecord()
{
string userId = (HttpContext.Current.User.Identity.GetUserId());
SqlDataAdapter Adp = new SqlDataAdapter("select * from Incomings where AspNetUsersId = '" + userId +"'", con);
DataTable Dt = new DataTable();
Dt.AcceptChanges();
Adp.Fill(Dt);
grid1.DataSource = Dt;
grid1.DataBind();
return Dt;
}
public void DeleteRowButton_Click(object sender, EventArgs e)
{
}
Cheers in advance for any help. I'm sure it's a simple resolution
You need a way for your code to know which ID to delete. Here is how I would normally do it:
Replace your button with an ItemTemplate, and add the button in here instead:
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button Text="Delete" runat="server" CommandArgument='<%# Eval("userId") %>' CommandName="Delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
When you have the button this way, you now have access to a CommandArgument and CommandName attributes. Notice the argument I am passing is Eval("userId"), the command name (as you will see later) is used to recognize what action you want to execute (this could be anything, is just a name).
Replace the CommandArgument with whatever value(s) you want to pass to the server, using the name that came from the database/datasource (I am guessing it would be userId).
Then, to capture this you need to implement the RowCommand event of the GridView, and intercept the correct CommandName:
public void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
string userId = e.CommandArgument.ToString();
//do something with the id
}
}
Here you have to make sure the CommandName in your button, matches to whatever action you want to execute in the RowCommand. This should do the trick.
Don't forget to bind the event to your GridView:
<asp:GridView OnRowCommand="GridView1_RowCommand" ID="GridView1" runat="server">
...
</asp:GridView>
just use this for the front-end code
<asp:GridView ID="grid1" OnRowDeleting="OnRowDeleting" DataKeyNames="deleteR" runat="server" AutoGenerateColumns="False" CellPadding="4" GridLines="None" style="width:100%" >
<columns>
<asp:TemplateField HeaderText="Delete Row">
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" class="btn btn-primary" Text="Delete" CommandName="Delete" OnRowDataBound="OnRowDataBound" />
</ItemTemplate>
</asp:TemplateField>
And have this in behind it:
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
int deleteR= Convert.ToInt32(grid1.DataKeys[e.RowIndex].Values[0]);
//have a sql statement here that add's the parameter ID for the row you want to delete, something like
SqlCommand com = new SqlCommand ("Delete FROM yourdatabase Where yourID = #yourID"
com.Parameters.AddWithValue("#yourID", yourID)
}
What you're looking for is indeed a simple solution.
You can use a foreach loop to search all DataRows within the DataTable for some kind of ID.Here's an example of what I mean:
String s = "/* IncomingsId for what you want to delete */";
foreach (DataRow r in dt.Rows) {
if (r["IncomingsId"].ToString().Equals(s)) {
dt.Rows.Remove(r);
}
}
Just a quick update for anyone that's helped me, thanks for your advice.
Asp.Net has it's own built in AutoGenerateDeleteButton and I set that to true and ran a bit of code behind it.
A simple solution that really shouldn't have taken me all day to complete!

Code Behind can't find a nested SQL connection in a List View

I have one ListView nested in another one as follows:
<asp:ListView ID="ListView1" runat="server" DataSourceID="editorMenuLinks" OnDataBound="ListView1_DataBound">
<ItemTemplate>
<asp:ListView ID="ListView2" runat="server" DataSourceID="test2" DataKeyNames="ID_connection" InsertItemPosition="LastItem">
</asp:ListView>
<asp:SqlDataSource runat="server" ID="test2">
</asp:SqlDataSource>
</ItemTemplate>
Code Behind
protected void ListView1_DataBound(object sender, EventArgs e)
{
test2.SelectParameters["-------"].DefaultValue = HttpContext.Current.User.Identity.GetUserId();
}
Unfortunately the SqlDataSource test2 can't be found in code behind. I get an error that the connection (test2) doesn't exist in the current context. Any tip?
Thanks
You can find controls inside the listview by doing
Listview1.FindControl("Name of Control")
Assign this to an instance of a sqlDataSource for example.
Dim Test2 as SqlDataSource = Listview1.FindControl("Test2")

Why is my Edit Function Showing all Column entries?

I have a webapp that calls on a SQL Query for a list of applications impacted by a project. I want my admins to be able to click edit and add remove applications to this list at will. Currently when they click edit they see every single Application that is Impacted by ANY project as part of the list box even though in the Gridview they only see the Applications Impacted by that specific project. When I hard code the value for the project it works, but I need it to be a variable depending on which project my admins click on to edit.
select
Applications.ApplicationName,
Projects.ProjectName
from ImpactedApplications
inner join Applications
on ImpactedApplications.AppId=Applications.AppId
inner join Projects
on ImpactedApplications.ProjectId=Projects.ProjectId
Where Projects.ProjectId=57 <--This is Hardcoded. I need this to be dynamic.
Adding Code
<asp:TemplateField HeaderText="ImpactedApplications">
<EditItemTemplate>
<asp:ListBox ID="ListBox1" runat="server" DataSourceID="ImpactedApps"
DataTextField="ApplicationName" DataValueField="ProjectName" Width="250px"></asp:ListBox>
<asp:Button ID="Button1" runat="server" Text="Add" />
<asp:Button ID="Button2" runat="server" Text="Remove" />
<asp:ListBox ID="ListBox3" runat="server" DataSourceID="Applications"
DataTextField="ApplicationName" DataValueField="AppId" Width="250px">
</asp:ListBox>
<br />
<asp:SqlDataSource ID="ImpactedApps" runat="server"
ConnectionString="<%$ ConnectionStrings:LandscapeServicesConnectionString %>"
SelectCommand="select Applications.ApplicationName, Projects.ProjectName
from ImpactedApplications
inner join Applications
on ImpactedApplications.AppId=Applications.AppId
inner join Projects
on ImpactedApplications.ProjectId=Projects.ProjectId
where Projects.ProjectName=#Projectname">
<SelectParameters>
<asp:FormParameter DefaultValue="PO Consolidation (EDW)"
FormField="Gridview1 - Column[2] - Project Name" Name="Project Name" />
</SelectParameters>
</asp:SqlDataSource>
Adding Background Code
public partial class Update : System.Web.UI.Page
{
public string query { get; set; }
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["LandscapeServicesConnectionString"].ConnectionString);
DataSet dt = new DataSet();
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
}
}
Create a parameterized query:
select
Applications.ApplicationName,
Projects.ProjectName
from ImpactedApplications
inner join Applications
on ImpactedApplications.AppId=Applications.AppId
inner join Projects
on ImpactedApplications.ProjectId=Projects.ProjectId
where Projects.ProjectId=#projectId
Then when you create your SqlCommand add a parameter and give it the value from your form:
cmd.Parameters.AddWithValue("#projectId",projectId);

Listview Update not workng

I'm trying to change the Select Command my DataSource uses using a dropdownlist. When the page loads it sets the select command depending on the selected index. When I change the dropdownlist the page refreshes but the data doesn't! Where am I going wrong?
.aspx file
<asp:DropDownList ID="filmFilter" runat="server" OnSelectedIndexChanged="filmFilter_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem Value="">Filter</asp:ListItem>
<asp:ListItem Value="priceASC">Price: Low-High</asp:ListItem>
<asp:ListItem Value="priceDSC">Price: High-Low</asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionStringFilms %>"></asp:SqlDataSource>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="filmID" DataSourceID="SqlDataSource1" OnSelectedIndexChanged="ListView1_SelectedIndexChanged">
<ItemTemplate>
...
</ItemTemplate>
<LayoutTemplate>
...
</LayoutTemplate>
</asp:ListView>
code-behind - page load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (filmFilter.SelectedIndex == 0)
{
SqlDataSource1.SelectCommand = "SELECT * FROM [films]";
}
if (filmFilter.SelectedIndex == 1)
{
SqlDataSource1.SelectCommand = "SELECT * FROM [films] ORDER BY [filmPrice]";
}
if (filmFilter.SelectedIndex == 2)
{
SqlDataSource1.SelectCommand = "SELECT * FROM [films] ORDER BY [filmPrice] DESC";
}
}
}
Thanks!
You've got it so your datasource is set on the page_load which is fine but you've wrapped it in
if (!IsPostBack)
{
Which means your code to change the datasource will only happen when you are not in postback (when you change the value of the dropdown you will be in a postback)
Have a read through
http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx
It will help with your understanding

How should I be using GridViews?

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" />

Categories