I have a DataList and inside of each item there is an ImageButton that needs to save the contents of an associated textarea. I normally would pass parameters using the CommandArgument tag, but the text inside the description is very long and I do not want to write it out into the commandargument for all the items being displayed. Instead, how can I find the ID of the associated textarea so I can save the text the user changes/enters?
I tried passing 'this' into the commandargument but I do not think it is working as it just passes the object for the button and not the whole item.
I realize this seems like a basic question but I've searched for over an hour. Your help is very appreciated.
<asp:ImageButton ID="saveDesc" runat="server" AlternateText="Save Image Description" BorderStyle="None" ImageUrl="..\..\images\save.png" CommandArgument='this' CommandName="SaveDescription" />
<asp:TextBox ID="description" runat="server" Text='<%#Eval("description")%>' style="font-weight:bold; width:100%" TextMode="MultiLine" Height="50px"/>
There are actually multiple DataLists inside of multiple Accordion views, but I'm not sure if this is relevant to the answer.
Thanks
You can do like...
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName == "SaveDescription")
{
DataListItem item = ((DataListItem)((ImageButton)e.CommandSource).NamingContainer);
TextBox description = (TextBox)item.FindControl("description");
description.Text // return your text
}
}
Related
I have a ASP.NET datagrid which is on a user control. I have a main page which adds the user control ( sometimes multiple copies of the user control ) and restores them when a post back occurs.
The dataGrid has insert / edit / delete links. I can add multiple copies of the user control to the page and the insert / edit delete functionality works perfectly for each separate control.
Yesterday I added some property binding to the main page to which are unrelated to the user control using the format Text='<%# DocumentTitle %>'. Initially I couldn't get this to work until I added Page.DataBind(); to the main page's Page_Load method. At this point the property binding started working correctly but then I noticed the insert functionality had stopped working in the datagrid within each user control....I debugged and found that when the following line executes it finds the text fields in the controls within the dataGrid to be empty or "":
eInfo.Ref = ((TextBox)gvEG.FooterRow.FindControl("txtEmployeeName")).Text;
If I remove the page.DataBind() method from the main page then the property binding stops working but the dataGrid(s) in the userControl start working.
My question is two fold i) Why does the seemingly unrelated change effect the dataGrid and ii) what do I do to get this working?
I've added the relevant sections of my code below...or at least what I think are the relevant sections.
Default.aspx
<div class="general">
<asp:TextBox Width="488" runat="server" placeholder="Document Title" Text='<%# DocumentTitle %>'></asp:TextBox>
</div>
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Create an empty user control for the first requirements section.
EmployeeSectionUserControl myUserControl1 = (EmployeeSectionUserControl )LoadControl("~/EmployeeSectionUserControl .ascx");
// Add it to the panel control holding all the user controls.
MainPanel.Controls.Add(myUserControl1);
DocumentTitle = "I am the default document title and I'm bound.";
}
else
{
// Do nothing
}
Page.DataBind();
}
EmployeeSectionUserControl.ascx
<asp:GridView ID="gvEG" runat="server" AutoGenerateColumns="False" CssClass="grid"
AlternatingRowStyle-CssClass="gridAltRow" RowStyle-CssClass="gridRow" ShowFooter="True"
EditRowStyle-CssClass="gridEditRow" FooterStyle-CssClass="gridFooterRow" OnRowCancelingEdit="gvEG_RowCancelingEdit"
OnRowCommand="gvEG_RowCommand" OnRowDataBound="gvEG_RowDataBound" OnRowDeleting="gvEG_RowDeleting"
OnRowEditing="gvEG_RowEditing" OnRowUpdating="gvEG_RowUpdating" DataKeyNames="Id" ShowHeaderWhenEmpty="true">
<Columns>
<asp:TemplateField HeaderText="Id" HeaderStyle-HorizontalAlign="Left" ControlStyle-Width="50px">
<ItemTemplate>
<%# Eval("Id")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Ref" HeaderStyle-HorizontalAlign="Left" ControlStyle-Width="90px">
<EditItemTemplate>
<asp:TextBox ID="txtEmployeeName" runat="server" Text='<%# Bind("Ref") %>'
Width="90px"></asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtEmployeeName" runat="server" Width="90px"></asp:TextBox>
</FooterTemplate>
EmployeeSectionUserControl.ascx.cs
protected void gvEG_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("Insert"))
{
employeeInfo eInfo = new employeeInfo();
eInfo.Id = 999;// Convert.ToInt32(((TextBox)gvEG.FooterRow.FindControl("Id")).Text);
// If we're inserting from the EmptyDataTemplate( ie an empty table ) of the gridview then we need to retreive the data differently.
// So we perform a check on the gridView FooterRow and if it's null then we can assume it's an empty table.
if (gvEG.FooterRow == null)
{
TextBox referenceTxtBox = (((Control)e.CommandSource).NamingContainer).FindControl("txtEmployeeName") as TextBox;
eInfo.Ref = referenceTxtBox.Text;
}
else
{
eInfo.Ref = ((TextBox)gvEG.FooterRow.FindControl("txtEmployeeName")).Text;
eInfo.Need =
}
// Store Update and Re-bind data to grid.
}
}
Page.DataBind() calls DataBind on it's children, so it updates DocumentTitle in the text box but it also DataBinds your grid. I didn't see a DataSource set in your grid, like an EntityDataSource, so I am assuming you are doing the smart retrieving (and preparation) of the data yourself in code and set the DataSource yourself:
gvEg.DataSource = someCollection;
gvEg.DataBind();
On the get your are loading the user-control and probably call this DataBind with specifying the DataSource. It binds and then you call Page.DataBind() which probably also triggers another DataBind for gvEg but since DataSource is set it shows the same.
On the post back you shouldn't do a DataBind() before handling events. Your call of Page.DataBind() does that. It triggers a DataBind() without a DataSource. Then the rowCommand comes and checks for the TextBox in the Footer which is cleared due to a DataBind with no elements.
What you should do is:
You shouldn't use Page.DataBind(). If you do so, you need todo it at a moment when all DataSources are set correctly and it shouldn't be kicked of during a post back. In general, I would not recommend using it because it makes it more complex and it's probably only helping a bit if you haven't set up your application correctly.
In your case it's definitely not necessary. Your textBox is a server control that's not part of any binding (GridView, Repeater, ListView). So your textBox is immediately available in your code behind.
So you should:
Give the textBox an ID you can use like txtDocumentTitle
<asp:TextBox Width="488" ID="txtDocumentTitle" runat="server" placeholder="Document Title"></asp:TextBox>
Replace setting DocumentTitle (unless you need it for something else too) with:
txtDocumentTitle.Text = "I am the default document title and I'm bound.";
Remove Page.DataBind();
So access server controls you have access immediately since they are also properties in your page or control.
I have a GridView with several BoundFields from a compact SQL database (I am using the older Visual Studio Express 2010, in C#)
I am experimenting, and have read that if your GridView fields are BoundFields rather than Template, extraction of the value should be as easy as:
Label.Text = GridView1.SelectedRow.Cells[0].Text;
(considering you are aiming for the value of the selected row)
I am trying to show that value in a Modal Popup Extender, and it's showing blank. No error message at all, and the debugger just shows the value blank all the time. Since I am quite a beginner, I am guessing that probably my error is in the placement of the parts, but I couldn't figure it out:
My GridView definition has this:
onselectedindexchanged="GridView1_SelectedIndexChanged"
Then later on I have a Panel with a Modal Popup Extender:
<asp:Panel ID="view" runat="server" CssClass="pnlBackGround">
<asp:Label ID="vid" runat="server" ></asp:Label>
<asp:Button ID="vclose" runat="server" Text="Cerrar" />
</asp:Panel>
<ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender2"
PopupControlID="view"
OkControlID="vclose"
TargetControlID="f1"
BackgroundCssClass="modalBackground"
runat="server">
</ajaxToolkit:ModalPopupExtender>
And the function that is giving me problems is the one called on selected index changed:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
vid.Text = GridView1.SelectedRow.Cells[0].Text;
this.ModalPopupExtender2.Show();
}
I think that this code should grab the value of the first cell of the selected row, and place it as text of the "vid" label, and then open the popup extender with that information.
What (probably silly) thing am I doing wrong?
I have a control image in a user control. And I'm using a repeater to create several images list.
I have a button outside from the user control to delete image (per images).
I want to know, how can I make references to an specific row when I click in the button to delete the image.
This is the repetear:
<asp:Repeater ID="ImageRepeater" runat="server"
onitemcommand="ImageRepeater_ItemCommand">
<ItemTemplate>
<div>
<uc1:IVT_DisplayImage ID="IVT_DisplayImage1" runat="server" ImageURL="<%# Container.DataItem %>" />
<asp:Button ID="RemoveDiplayImage" Text="Remove" runat="server"
CommandName="delete"
/>
</div>
</ItemTemplate>
</asp:Repeater>
This is the event ItemCommand:
protected void ImageRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "delete")
{
//????
}
}
I want to know, how identify by code wich row (user control) I'm selecting.
You need to add CommandArgument to your button like CommandArgument="<%# Container.ItemIndex %>".
This way, in the code; e.CommandArgument gives you the item number, with which you can get the item that you want.
Note: In fact instead of specifying ItemIndex as CommandArgument, you can use any Primary Key (Unique Identifier) from the DataSource that you bind to the repeater from where you will be able to get hold of the record directly from the list object (DataSource).
In asp.net I have a table in database containing questions,date of submission and answers.On page load only questions appear.now i want to use any link which on clicking show answers and date specified in table data, either in textbox or label and clicking again on that link answer disappear again like expand and shrink on click.
So what coding should i use for this in C#?
I believe you could handle the ItemCommand event of the Repeater.
Place a LinkButton control for the link that you want the user to click in the Repeater's item template. Set the CommandName property of this to something meaningful, like "ShowAnswers". Also, add a Label or TextBox control into the Repeater's item template, but set their Visible property to false within the aspx markup.
In the code-behind, within the ItemCommand event handler check if the value of e.CommandName equals your command ("ShowAnswers"). If so, then find the Label or TextBox controls for the answers and date within that Repeater item (accessed via e.Item). When you find them, set their Visible property to true.
Note: you could take a different approach using AJAX to provide a more seamless experience for the user, but this way is probably simpler to implement initially.
I think the implementation would look something like this. Disclaimer: I haven't tested this code.
Code-Behind:
void Repeater_ItemCommand(Object Sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "ShowAnswers")
{
Control control;
control = e.Item.FindControl("Answers");
if (control != null)
control.Visible = true;
control = e.Item.FindControl("Date");
if (control != null)
control.Visible = true;
}
}
ASPX Markup:
<asp:Repeater id="Repeater" runat="server" OnItemCommand="Repeater_ItemCommand">
<ItemTemplate>
<asp:LinkButton id="ShowAnswers" runat="server" CommandName="ShowAnswers" />
<asp:Label id="Answers" runat="server" Text='<%# Eval("Answers") %>' Visible="false" />
<asp:Label id="Date" runat="server" Text='<%# Eval("Date") %>' Visible="false" />
</ItemTemplate>
</asp:Repeater>
I wanted to do a datagrid that had the allowed a user to edit current information as well as add new stuff. I also need it to have a checkbox in there that I can respond to. Basically it would be a name, and an isActive field that was represented by a checkbox in each row of the datagrid.
I would like to use linq for this but am not sure if it's even possible. This is a ASP.Net website.
If anyone had any feedback that would be awesome.
Easy enough to do.
The GridView has a number of events that you can use for certain operations (Delete, Edit, Cancel, and Update). For example, the OnRowUpdating and OnRowEditing would look like thus:
<asp:GridView ID="gvTest" runat="Server" OnRowUpdating="gvTest_RowUpdating" OnRowEditing="gvTest_RowEditing">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnUpdate" runat="Server" Text="Update" CommandName="Update">
<asp:Button ID="btnEdit" runat="Server" Text="Edit" CommandName="Edit">
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then implement the event handlers for the update (edit, delete, etc.) in your codebehind. To make life easier for yourself, you can switch over to Design view, find your GridView and bring up the Events (the icon that looks like a lightning bolt) and then double click an event and the stub of it will automatically be created for you in the codebehind and the html markup will automatically be created as well. An example of the RowUpdating event handler would look like thus:
protected void gvTest_RowUpdating(object sender, GridViewUpdateEventArgs e) {
// Convenient access to the row index that was selected
int theRowIndex = e.RowIndex;
GridViewRow gvr = gvTest.Rows[e.RowIndex];
// Now its just a matter of tracking down your various controls in the row and doing
// whatever you need to with them
TextBox someTxtBox = (TextBox)gvr.FindControl("theTextBoxID");
DropDownList someDDL = (DropDownList)gvr.FindControl("theDDL_ID");
// Perhaps some business class that you have setup to take the value of the textbox
// and insert it into a table
MyDoSomethingClass foo = new MyDoSomethingClass {
FirstName = someTxtBox.Text,
Age = someDDL.SelectedItem.Value
};
foo.InsertPerson();
}
Note that you can also use the OnRowCommand instead of using Update (Edit, Delete, etc.) events, but the OnRowCommand doesn't have the selected row index readily available for you. If you want it then you have to do a little magic in your markup.
<asp:Button ID="btnDoSomething" runat="Server" Text="Do Something" CommandArgument="<%# Container.DataItemIndex %>" CommandName="DoSomething">
And then in the RowCommand event you do something like this to get at the row index:
protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e) {
int rowIdx = Convert.ToInt32(e.CommandArgument);
}
EDIT:
Accessing the key(s) that your GridView is bound to is quite simple, actually. Assuming that your GridView is bound to only one key, you can get the key in this manner (assume that we're in the RowCommand event):
int rowIdx = Convert.ToInt32(e.CommandArgument);
int someKeyID = Convert.ToInt32(gvTest.DataKeys[rowIdx].Value);