In ASP.NET, we like using "child" SqlDataSource inside a bound grid server control (Girdview or ListView).
I've been using this FindControl() approach for years:
C# Codebehind:
protected void gridviewItems_RowDataBound(object sender, GridViewRowEventArgs e)
{
Label labelItemId = (Label)e.Row.FindControl("labelItemId");
}
or like this:
protected void buttonSend_Click(object sender, EventArgs e)
{
Label labelItemId = (Label)((Control)sender).NamingContainer.FindControl("labelItemId");
}
Nothing wrong with it, but I'm quite tired of it and maybe there's a way to do this in .aspx markup?
Something like:
<asp:DropDownList
ID="dropdownItems"
runat="server"
DataSource=<% this.NamingContainer.FindControl("slqdatasourceItems") %>
DataTextField="ItemName"
DataValueField="ItemId" />
Is this possible?
I am not sure what your situation is. Do you have something like this?
namespace WebApplication1
{
public class Person
{
private string name;
public string Name
{
set
{
name = value;
}
get
{
return name;
}
}
public List<Person> GetAll()
{
List<Person> persons = new List<Person>();
Person p1 = new Person();
p1.Name = "John";
persons.Add(p1);
return persons;
}
}
}
<form id="form1" runat="server">
<div>
<asp:GridView runat="server" ID="dataGrid" AutoGenerateColumns="false" DataSourceID="persons">
<Columns>
<asp:BoundField HeaderText="Person Name" DataField="Name" />
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList runat="server" DataTextField="Name" DataSourceID="persons"></asp:DropDownList>
<asp:ObjectDataSource runat="server" ID="persons" TypeName="WebApplication1.Person" SelectMethod="GetAll"></asp:ObjectDataSource>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource runat="server" ID="persons" TypeName="WebApplication1.Person" SelectMethod="GetAll"></asp:ObjectDataSource>
</div>
</form>
This is a web form with a gridview which has a "child" datasource pointing to the class Person and it´s method GetAll. There arise no problems at all. Please post some complete markup with your situation.
Edit
If you have something like this:
<asp:ListView runat="server" ID="lv" DataSourceID="SqlDataSource1">
<LayoutTemplate><div runat="server" id="itemPlaceholder"></div></LayoutTemplate>
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("Name") %>'></asp:Label>
<asp:Button runat="server" CommandName="Edit" Text="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:Label runat="server" Text='<%# Eval("Name") %>'></asp:Label>
<asp:DropDownList ID="DropDownList1" runat="server" DataTextField="Name" DataSourceID="SqlDataSource1"></asp:DropDownList>
<asp:SqlDataSource id="SqlDataSource1" runat="server" DataSourceMode="DataReader"
ConnectionString="<%$ ConnectionStrings:SqlConnectionString%>" SelectCommand="SELECT Name FROM Person">
</asp:SqlDataSource>
</EditItemTemplate>
</asp:ListView>
<asp:SqlDataSource id="SqlDataSource1" runat="server" DataSourceMode="DataReader"
ConnectionString="<%$ ConnectionStrings:SqlConnectionString%>" SelectCommand="SELECT Name FROM Person">
</asp:SqlDataSource>
you shouldn´t have any problems either. I am here a assuming that you are drawing data from a table named "Person". Please show your special case as this is of course a simple setup.
Related
I am so frustrated. Using asp.net GridView. Using a LinkButton with the CommandName="Delete". Don't understand why the page isn't posting back. I've done this a million times in other apps. I've compared them against one another and nothing appears different. I will preface by saying this IS someone else's template, however, so it's not my same template.
Any ideas what might be causing my issues?
My scenario is this:
ASPX Page (edited to add the HTML; there's more HTML in the site.Master and there's also a tag for the AjaxControlToolkit at the top of the page):
<div class="width80 container body-content">
<h2 class="marginTop50">Message Board</h2>
<asp:Panel ID="pnlMsgsForUser" runat="server" Visible="false">
<div class="jumbotronSmallFont">
<asp:Label ID="lblErrorMessage" CssClass="has-error" runat="server"></asp:Label>
</div>
</asp:Panel>
<div class="jumbotronSmallFont">
<h4>New Message</h4>
<form>
<div class="form-group">
<label for="messageBody">Message Body</label>
<textarea class="form-control" id="messageBody" rows="3" style="max-width: 600px;"></textarea>
</div>
<div class="text-center">
<button id="btnSave" class="btn btn-primary" style="width: 75px;">Save</button>
<button type="button" id="btnReset" class="btn btn-default marginLeft15px" style="width: 75px;">Reset</button>
</div>
</form>
</div>
<div>
<asp:GridView ID="gvMessages" runat="server" Width="100%"
CssClass="table adminMessageBoardTable marginAuto" AutoGenerateColumns="False"
OnRowUpdating="gvMessages_RowUpdating"
OnRowCancelingEdit="gvMessages_RowCancelingEdit"
OnRowDataBound="gvMessages_RowDataBound"
OnRowEditing="gvMessages_RowEditing"
OnRowDeleting="gvMessages_RowDeleting"
DataKeyNames="Id" BorderStyle="NotSet">
<Columns>
<asp:TemplateField HeaderText="Message" HeaderStyle-CssClass="center" SortExpression="Message">
<EditItemTemplate>
<asp:TextBox ID="txtMsg" Width="100%" runat="server"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("MessageBody") %>' ID="lblMessage"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date Updated" SortExpression="DateUpdated" HeaderStyle-CssClass="center" ItemStyle-CssClass="center">
<HeaderStyle Width="120px" />
<EditItemTemplate>
<asp:Label runat="server" ID="lblEditDateUpdated" Enabled="false"></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("DateUpdated","{0:d}") %>' ID="lblDateUpdated"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Updated By" SortExpression="UpdatedBy" HeaderStyle-CssClass="center" ItemStyle-CssClass="center">
<HeaderStyle Width="120px" />
<EditItemTemplate>
<asp:Label runat="server" Text="" ID="lblEditUpdatedBy" Enabled="false"></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("UpdatedBy") %>' ID="lblUpdatedBy"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-CssClass="center">
<HeaderStyle Width="120px" />
<EditItemTemplate>
<asp:LinkButton ID="lbUpdate" runat="server" CausesValidation="True"
CommandName="Update" Text="Update"
OnClientClick="return confirm('You are about to update this entry. \n\nDo you wish to proceed?');"></asp:LinkButton>
<asp:LinkButton ID="lbCancel" runat="server" CausesValidation="False"
CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="lbEdit" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="lbDelete" runat="server" CommandArgument='<%# Eval("Id") %>' CausesValidation="False"
CommandName="Delete" Text="Delete" OnClientClick="return confirm('You are about to delete this entry. \n\Do you wish to proceed?');"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
In my code-behind, I have:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var user = CommonFunctions.GetUserID(true);
var Admin = Roles.IsUserInRole(user, "Administrator");
var Dev = Roles.IsUserInRole(user, "Developer");
if (!Admin && !Dev)
{
Response.Redirect("~/");
}
gvBind(true);
}
}
When I click on the Delete linkbutton for a row, it drops into the Page_Load and
!Page.IsPostBack
verifies as true. I have no idea why it's doing this. It also never even hits the RowDeleting command. My breakpoint is so sad.
In my other app, all the markup and code-behind are pretty much the same. The only differences are the gridview name and the Eval tags. But when I click Delete in that app, it skips the !Page.IsPostBack section. :( It also obviously fires the RowDeleting.
I've also tried implementing RowCommand, but that event never fires either. It only does Page_Load and RowDataBound before essentially refreshing the page.
Any ideas?
Please, and thanks!!!
Your code is working fine. When I click Delete button, it triggers gvMessages_RowDeleting event. Here is how I test it -
<asp:GridView ID="gvMessages" runat="server" Width="100%"
CssClass="GridView marginAuto" AutoGenerateColumns="False"
OnRowDeleting="gvMessages_RowDeleting"
DataKeyNames="Id">
<Columns>
<asp:TemplateField HeaderText="Message" HeaderStyle-CssClass="center" SortExpression="Message">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("MessageBody") %>' ID="lblMessage"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-CssClass="center">
<ItemTemplate>
<asp:LinkButton ID="lbDelete" runat="server" CommandArgument='<%# Eval("Id") %>' CausesValidation="False"
CommandName="Delete" Text="Delete"
OnClientClick="confirm('You are about to delete this entry. \n\Do you wish to proceed?');"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind
public class Item
{
public int Id { get; set; }
public string MessageBody { get; set; }
}
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
gvMessages.DataSource = new List<Item>
{
new Item {Id = 1, MessageBody = "One"},
new Item {Id = 2, MessageBody = "Two"},
new Item {Id = 3, MessageBody = "Three"},
};
gvMessages.DataBind();
}
}
protected void gvMessages_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
}
}
OnClientClick="return confirm('Are you sure?');"
Try to add the return from your confirm statement.
I am trying to execute an "INSERT INTO" command by using the asp:SqlDataSource InsertCommand in a C# statement ".Insert()".
The Button, "btninsert", resides in the header field of a gridview as does the inserting Textboxes: "TextBoxHeadercol1", "TextBoxHeadercol2" and "TextBoxHeadercol3".
I have 4 columns in my table, "test", they are "idt", "col1", "col2", "col3". My Gridview is "gvtotal".
I know that col1, col2 and col3 will print no data because I left out ItemTemplate with the labels.
public void btninsert_Click(object sender, EventArgs e)
{
SqlDataSource1.InsertParameters["col1"].DefaultValue = ((TextBox)gvtotal.HeaderRow.FindControl("TextBoxHeadercol1")).Text;
SqlDataSource1.InsertParameters["col2"].DefaultValue = ((TextBox)gvtotal.HeaderRow.FindControl("TextBoxHeadercol2")).Text;
SqlDataSource1.InsertParameters["col3"].DefaultValue = ((TextBox)gvtotal.HeaderRow.FindControl("TextBoxHeadercol3")).Text;
SqlDataSource1.Insert();
}
<asp:GridView ID="gvtotal"
runat="server"
DataSourceID="SqlDataSource1"
AutoGenerateColumns="False"
DataKeyNames="idt">
<Columns>
<asp:BoundField DataField="idt" HeaderText="idt" Readonly="true" SortExpression="idt" />
<asp:TemplateField SortExpression="col1">
<HeaderTemplate>
<asp:TextBox ID="TextBoxHeadercol1" text="col1" runat="server" MaxLength="40" />
</HeaderTemplate>
</asp:TemplateField>
<asp:TemplateField SortExpression="col2">
<HeaderTemplate>
<asp:TextBox ID="TextBoxHeadercol2" text="col2" runat="server" MaxLength="40" />
</HeaderTemplate>
</asp:TemplateField>
<asp:TemplateField SortExpression="col3">
<HeaderTemplate>
<asp:TextBox ID="TextBoxHeadercol3" text="col3" runat="server" MaxLength="40" />
</HeaderTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<asp:Button ID="btninsert" runat="server" Text="Insert Into" OnClick="btninsert_Click" />
</HeaderTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource
id="SqlDataSource1"
ConnectionString="<%$ ConnectionStrings:connone %>"
SelectCommand="SELECT * FROM [test];"
InsertCommand="INSERT INTO [test] [col1],[col2],[col3] VALUES #col1,#col2,#col3;"
runat="server"
/>
I think you might get away with this by using InsertCommand template provided by SQLDataSource. Write this command for SQLDataSource for
InsertCommand = "INSERT INTO Test(….) VALUES(#val1,#val2,#val3)
Use SQLDataSource template to map #val1, #val2 and #val3 to text boxes you want. The provided quick template will facilitate this. In the click event for Insert, simply refresh grid view view to display the new contents
public void btninsert_Click(object sender, EventArgs e)
{
gridview.DataBind();
}
Note that I do not have Visul Studio on my machine. Assume the above code as pseudo code
I want to have a GridView with static data in it, not linked to any database or data source, and I would like to hard-code it directly in my aspx file.
I'm brand new to ASP.NET and have no idea what I'm doing, and for whatever reason I can't find anything online about how to do this.
I'm trying to create a one-column table with a heading of "Hello World" and two data items, "Hello" and World". Here is what I'm trying, but nothing is showing up on the page when I run it:
<asp:GridView ID="GridView" runat="server">
<Columns>
<asp:TemplateField HeaderText ="Hello World">
<ItemTemplate>
<asp:Label ID="lblHello" runat ="server" Text ="Hello"/>
</ItemTemplate>
<ItemTemplate>
<asp:Label ID="lblWorld" runat ="server" Text ="World"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You want to assign either IEnumerable, DataSet or DataTable to display data in GridView.
<asp:GridView ID="GridView" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="Hello World">
<ItemTemplate>
<asp:Label ID="lblHello" runat="server"
Text='<%# Eval("Text1") %>' />
<asp:Label ID="lblWorld" runat="server"
Text='<%# Eval("Text2") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
public class Item
{
public string Text1 { get; set; }
public string Text2 { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
GridView.DataSource = new List<Item>
{
new Item {Text1 = "Hello", Text2 = "World"}
};
GridView.DataBind();
}
Updated:
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
GridView.DataSource =
new Dictionary<string, string> { { "Hello", "World" } };
GridView.DataBind();
}
</script>
<asp:GridView ID="GridView" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="Hello World">
<ItemTemplate>
<asp:Label ID="lblHello" runat="server"
Text='<%# Eval("Key") %>' />
<asp:Label ID="lblWorld" runat="server"
Text='<%# Eval("Value") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I have a page where I display a list of groups for my application. There can be multiple users in a group. The group list is implemented with a gridview. Besides the column for the group description, the gridview has a button for adding users to it. When I click this button, the groupid is passed to a new page, on this page there is another gridview with a list of users. The gridview also has a buttonfield for adding that specific user to the group's group id. For this I have an extra table:
UserGroup
usergroupid
userid
groupid
My problem is, nothing is inserted into this table, the insert command is executed but something seems to be missing.
Here is my code:
Markup:
<asp:Content ID="content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:GridView OnRowCommand="grdBenutzer_RowCommand" ID="grdBenutzer" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField ReadOnly="true" DataField="BenutzerID" HeaderText="ID" />
<asp:TemplateField HeaderText="Bezeichnung">
<ItemTemplate>
<%# Eval("Bezeichnung")%>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList AppendDataBoundItems="true" runat="server" ID="ddwnBezeichnung" Text='<%# Bind("Bezeichnung")%>'>
<asp:ListItem Text="Mitarbeiter" Value="Mitarbeiter"></asp:ListItem>
<asp:ListItem Text="Praktikant" Value="Praktikant"></asp:ListItem>
<asp:ListItem Text="Azubi" Value="Azubi"></asp:ListItem>
<asp:ListItem Text="Umschüler" Value="Umschüler"></asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Vorname">
<ItemTemplate>
<%# Eval("Vorname")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtVorname" Text='<%# Bind("Vorname")%>' />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Nachname">
<ItemTemplate>
<%# Eval("Nachname")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtNachname" Text='<%# Bind("Nachname")%>' />
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField ReadOnly="true" HeaderText="Geburtsdatum" DataField="Geburtsdatum" />
<asp:TemplateField HeaderText="Benutzerart">
<ItemTemplate>
<%# Eval("Benutzerart")%>
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField ButtonType="Button" HeaderText="Mitglied hinzufügen" Text="Mitglied hinzufügen" CommandName="MitgliedHinzufuegen" />
</Columns>
</asp:GridView>
<asp:SqlDataSource OnInserted="SqlDataSource1_Inserted" ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [BenutzerID], [Bezeichnung], [Vorname], [Geburtsdatum], [Nachname], [Benutzerart] FROM [Benutzer] WHERE [Archiviert] != 1"
InsertCommand="INSERT INTO BenutzerGruppe (BenutzerID, GruppenID) VALUES (#BenutzerID, #GruppenID)">
</asp:SqlDataSource>
</asp:Content>
Code-behind:
protected void SqlDataSource1_Inserted(object sender, SqlDataSourceStatusEventArgs e)
{
Response.Redirect("Gruppenverwaltung.aspx");
}
protected void grdBenutzer_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "MitgliedHinzufuegen")
{
string gruppenid = Request.QueryString["GruppenID"];
SqlDataSource1.InsertParameters.Add("GruppenID", gruppenid);
SqlDataSource1.Insert();
}
}
The inserted method fires after I add an user to the group, but when I view the group's members, no user was added....
The insert command expects input parameter #BenutzerID which you don't appear to be providing in the code-behind.
i have a repeater control which contains grids, based on values from database, say for example i have 2 grids inside repeater control, now both the grids contains a column which have up and down buttons, now when user clicks on the button from any grids, how can i check from which grid the button is called.
below is my code where i am filling the grids on RepeaterItemDataBound Event
GridView gvw = e.Item.FindControl("grid") as GridView;
gvw.DataSource = info.GetStories(sectionNames[e.Item.ItemIndex].Trim());
gvw.DataBind();
here section name contains the name of the sections, based on number of sections, i generate the grids.
My Design looks like this:
<asp:Repeater ID="rptGrids" runat="server"
OnItemDataBound="rptGrids_ItemDataBound">
<ItemTemplate>
<asp:GridView ID="grid" runat="server" Width="100%" CellPadding="5" AllowPaging="true" ShowHeader="true" PageSize="10" AutoGenerateColumns="false" OnRowCommand="Stories_RowCommand">
<Columns>
<asp:BoundField DataField="ArticleID" HeaderText="Article ID" ItemStyle-CssClass="center" />
<asp:BoundField DataField="CategoryID" HeaderText="Category ID" ItemStyle-CssClass="center" />
<asp:BoundField DataField="Title" HeaderText = "Article Title" />
<asp:BoundField DataField="PublishDate" DataFormatString="{0:d}" HeaderText="Publish Date" ItemStyle-CssClass="center" />
<asp:TemplateField HeaderText="Select Action" ItemStyle-CssClass="center">
<ItemTemplate>
<asp:ImageButton ID="btnMoveUp" runat="server" ImageUrl="/images/up.gif" CommandArgument="Up" CommandName='<%# Container.DataItemIndex + "," + DataBinder.Eval(Container.DataItem, "StoryType") %>' />
<asp:ImageButton ID="btnMoveDown" runat="server" ImageUrl="/images/dn.gif" CommandArgument="Down" CommandName='<%# Container.DataItemIndex + "," + DataBinder.Eval(Container.DataItem, "StoryType") %>' />
<asp:ImageButton ID="btnDelete" runat="server" ImageUrl="/images/deny.gif" CommandArgument="Delete" OnClientClick="return confirm('Are you sure you want to delete this article?');" CommandName='<%# Container.DataItemIndex %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:HiddenField ID="hdStoriesSortOrder" runat="server" Value='<%# Eval("SortOrder") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div class="blank"></div>
</ItemTemplate>
</asp:Repeater>
this is my gridviews row_command event
protected void Stories_RowCommand(object sender, GridViewCommandEventArgs e)
{
int index = Convert.ToInt32(e.CommandName.Split(',')[0]);
string section = e.CommandName.Split(',')[1].Trim().ToString();
string command = e.CommandArgument.ToString();
if (command.ToLower() == "up")
{
GridView grd = rptGrids.Items[1].FindControl("grid") as GridView; // If i specify the index here, i gets proper grid, but how to recognize at runtime.
Response.Write(grd.Rows.Count);
}
else if (command.ToLower() == "down")
{
}
}
can anyone tell me how can i get from which grid up/down button has been clicked.
You can use command argument to pass required value.
Here is sample of using imagebutton in similar way:
<asp:ImageButton ID="btnView" runat="server" ToolTip="<% $resources:AppResource,Edit %>"
SkinID="EditPage" CommandName="myCommand" CommandArgument='<%# Eval("CustomerId") %>'
PostBackUrl='<%# "~/AdminPages/Customer.aspx?id=" + Eval("CustomerId").ToString() %>' />
Take notice on CommandArgument property.You can set it with value that indicates specific gridview inside repeater.
And here is how to check the value:
protected void EntityGridViewContacts_RowCommand(object sender, GridViewCommandEventArgs e)
{
//here you can check for command name...
switch (e.CommandName)
{
case "myCommand":
//here you access command argument...
int customerId = Convert.ToInt32(e.CommandArgument.ToString());
break;
}
//here is how you access source gridview...
GridView gridView = (GridView)sender;
string controlId = gridView.ID;
}
You can also set CommandArgument using this approach:
CommandArgument='<%# GetMySpecialValue() %>'
Then you should declare function on page side something like this:
public string GetMySpecialValue()
{
return "some value";
}