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";
}
Related
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();
}
I'm trying to accomplish inline editing with a DevExpress ASPxTreeList control on an ASP.NET 4.5 webforms application - something like this (taken from the DevExpress demo site):
What I'm trying to do are two things:
I'd like to be able to restrict my inline editing to just a few columns - e.g. only the Budget column should be editable. I'd like to have only the Budget cell turn into a textbox to allow data entry - while all other columns in the chosen row should remain as is - as labels basically (right now, when I enable inline editing, all cells turn into editable controls - they turn into a textbox that would suggest editing is possible)
I would love to be able to just click (or double-click) into that cell to enable inline editing - for now, I need to use a separate command button to "turn on" editing. How can I do this (if at all)?
If you want labels instead of editable controls, then you can simply use EditCellTemplate with label control inside.
Here is example:
<dx:TreeListDataColumn FieldName="ContactName">
<EditCellTemplate>
<dx:ASPxLabel ID="ASPxLabel1" runat="server" Value='<%# Eval("ContactName") %>' />
</EditCellTemplate>
</dx:TreeListDataColumn>
This functionality for ASPxTreeList does not implemented by DevExpress. They have suggestion in their Support Center to implement «ASPxTreeList - Implement BatchEdit mode (like in ASPxGridView)». Here you can take a look at how it works in ASPxGridView.
So, here is workaround, based on this example.
The main goal is to use DataCellTemplate for columns with ASPxTextBox control as value editor. The ASPxTextBox can be fully customized by applying a specific style to each composite editor element. This allows to simulate the desired behavior. You can hide the borders and background of ASPxTextBox and show the borders only when ASPxTextBox is focused.
Here is example:
<script>
function GotFocus(s, e) {
s.inputElement.style.cursor = "text";
}
function LostFocus(s, e) {
s.inputElement.style.cursor = "default";
}
</script>
<dx:ASPxTreeList ID="ASPxTreeList1" ClientInstanceName="tree" runat="server" Width="100%"
DataSourceID="AccessDataSource1" AutoGenerateColumns="False" KeyFieldName="CategoryID"
OnCustomCallback="ASPxTreeList1_CustomCallback">
<Columns>
<dx:TreeListTextColumn FieldName="CategoryID" ReadOnly="True" VisibleIndex="0">
</dx:TreeListTextColumn>
<dx:TreeListTextColumn FieldName="CategoryName" VisibleIndex="1">
<DataCellTemplate>
<dx:ASPxTextBox
ID="txtBox"
Width="100%"
runat="server"
Value='<%# Eval("CategoryName") %>'
Cursor="default"
BackColor="Transparent"
Border-BorderColor="Transparent"
FocusedStyle-Border-BorderColor="ActiveBorder"
ClientSideEvents-GotFocus="GotFocus"
ClientSideEvents-LostFocus="LostFocus" />
</DataCellTemplate>
</dx:TreeListTextColumn>
<dx:TreeListTextColumn FieldName="Description" VisibleIndex="2">
<DataCellTemplate>
<dx:ASPxTextBox
ID="txtBox"
Width="100%"
runat="server"
Value='<%# Eval("Description")%>'
Cursor="default"
BackColor="Transparent"
Border-BorderColor="Transparent"
FocusedStyle-Border-BorderColor="ActiveBorder"
ClientSideEvents-GotFocus="GotFocus"
ClientSideEvents-LostFocus="LostFocus"/>
</DataCellTemplate>
</dx:TreeListTextColumn>
</Columns>
<Border BorderWidth="0px" />
</dx:ASPxTreeList>
<dx:ASPxButton ID="ASPxButton1" runat="server" AutoPostBack="False" Text="Post Modifications"
Width="217px">
<ClientSideEvents Click="
function(s, e) {
tree.PerformCallback('post');
}" />
</dx:ASPxButton>
<asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="~/App_Data/nwind.mdb"
SelectCommand="SELECT * FROM [Categories]"
UpdateCommand="UPDATE [Categories] SET [CategoryName] = ?, [Description] = ? WHERE [CategoryID] = ?">
<UpdateParameters>
<asp:Parameter Name="CategoryName" Type="String" />
<asp:Parameter Name="Description" Type="String" />
<asp:Parameter Name="CategoryID" Type="Int32" />
</UpdateParameters>
</asp:AccessDataSource>
private List<Record> list = new List<Record>();
protected void Page_Load(object sender, EventArgs e)
{
var column1 = ASPxTreeList1.DataColumns["CategoryName"];
var column2 = ASPxTreeList1.DataColumns["Description"];
var nodes = ASPxTreeList1.GetVisibleNodes();
foreach (var node in nodes)
{
var txtBox1 = (ASPxTextBox)ASPxTreeList1.FindDataCellTemplateControl(node.Key, column1, "txtBox");
var txtBox2 = (ASPxTextBox)ASPxTreeList1.FindDataCellTemplateControl(node.Key, column2, "txtBox");
if (txtBox1 == null || txtBox2 == null)
continue;
int id = Convert.ToInt32(node.Key);
list.Add(new Record(id, txtBox1.Text, txtBox2.Text));
}
}
protected void ASPxTreeList1_CustomCallback(object sender, TreeListCustomCallbackEventArgs e)
{
if (e.Argument == "post")
{
for (int i = 0; i < list.Count; i++)
{
AccessDataSource1.UpdateParameters["CategoryName"].DefaultValue = list[i].CategoryName;
AccessDataSource1.UpdateParameters["Description"].DefaultValue = list[i].Description;
AccessDataSource1.UpdateParameters["CategoryID"].DefaultValue = list[i].Id.ToString();
// AccessDataSource1.Update(); << Uncomment this line to update data!
}
ASPxTreeList1.DataBind();
}
}
I know there are alot of questions&answers about this but non of them works for me
Trying to populate this Drop Down List via a function in code behind:
This drop down list is for Images names, when a user choose one and clicks the "Update" link button in the Grid View I need to insert a suffix to the image name (for the path),
so if the user choose an image name from the list the update button it will actually update the fileName + insert at the beginning the path, so it would be
../images/gary.jpg
for the name gary.
aspx page
<asp:TemplateField>
<EditItemTemplate>
<asp:DropDownList ID="ddlImages" runat="server">
<Items>
<asp:ListItem Text="Choose" Value="" />
</Items>
</asp:DropDownList>
</EditItemTemplate>
...
code behind
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlImages = (e.Row.FindControl("ddlImages") as DropDownList);
ShowImages(ddlImages);
}
}
"ddlImages" is null, how can I find him?
Managed to find the drop down list like that:
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList ddlImages = (DropDownList)e.Row.FindControl("ddlImages");
ddlImages.DataSource = GetImages();
ddlImages.DataBind();
}
}
Now i am facing another problem, in the aspx i have an "UpdateCommand" which take parameters and try to update the database. The problem- it need to take the dropDownList chosen value but instead it take: "" how can i change it to take the value that the user choose in the dropDownList
aspx page
UpdateCommand="UPDATE [investigator] SET [name] = #name, [area] = #area, [country] = #country, [picture] = #picture, [review] = #review WHERE [Id] = #Id">
<UpdateParameters>
<asp:Parameter Name="name" Type="String" />
<asp:Parameter Name="area" Type="String" />
<asp:Parameter Name="country" Type="String" />
<asp:Parameter Name="picture" Type="String" />
<asp:Parameter Name="review" Type="String" />
<asp:Parameter Name="Id" Type="Int32" />
</UpdateParameters>
Meaning- I have to change
<asp:Parameter Name="picture" Type="String" />
to drop down list selected value. How can I achieve that?
Regarding your question about the update Parameter, you should use the ControlParameter instead of general Parameter. Try replacing the Parameter Definition for the Dropdown list with following
code.
<asp:ControlParameter Name="picture" ControlID="ddlImages"
PropertyName="SelectedValue" Type="String" />
UPDATE
What you can do as alternate is,
Change the parameter back to
<asp:Parameter Name="picture" Type="String" />
Add RowUpdating event handler to the gridview
In the RowUpdating command set the data source parameter based on the selected value as below
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = GridView1.Rows[e.RowIndex];
DropDownList ddlImages= row.FindControl("ddlImages") as DropDownList;
SqlDataSource1.UpdateParameters["picture"].DefaultValue = ddlImages.SelectedValue;
}
I have an ASP.net with C# web app with an issue. On the app, the user can enter some data and click an "Add" button. This will generate a grid on the screen with the data the user just entered. There is also a text box for "Total Amount Requested". Below that, there is a label for "Remaining Amount". If the user puts 100.00 in the "Total Amount Requested" and then loads 75.00 into the grid, the "Remaining Amount" will show "25.00". This works fine. I added a delete row to the grid, so the user can delete specific rows. This also works. I added a _RowDeleted function to the grid, and then inserted the function to do the math for "Remaining Amount". Here is the issue:
When I delete the row, it deletes from the database, no issue. However, the label on the screen does not refresh. I put a stop in the code and walked through it. The script works, the label.text is loaded with what I expect, but it just won't refresh on screen. I've tried many different things but keep hitting a wall. Any help would be appreciated!
The Grid:
<dx:ASPxGridView ID="gridGL1" runat="server" AutoGenerateColumns="False"
DataSourceID="sdsGLData" KeyFieldName="GenLedgerID" OnRowDeleted="gridGL1_RowDeleted">
<Columns>
<dx:GridViewCommandColumn VisibleIndex="0" Caption=" " ButtonType="Button">
<DeleteButton Visible="True">
</DeleteButton>
</dx:GridViewCommandColumn>
<dx:GridViewDataTextColumn FieldName="GenLedgerID" Visible="false" VisibleIndex="1">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn FieldName="UnitNumber" VisibleIndex="2">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn FieldName="AccountNumber" VisibleIndex="3">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn FieldName="Amount" VisibleIndex="4">
</dx:GridViewDataTextColumn>
</Columns>
<SettingsBehavior ConfirmDelete="True" />
</dx:ASPxGridView>
The SDS:
<asp:SqlDataSource ID="sdsGLData" runat="server"
ConnectionString="<%$ ConnectionStrings:FEAPConnectionString %>"
ProviderName="<%$ ConnectionStrings:FEAPConnectionString.ProviderName %>"
SelectCommand="prcRequestGLList" SelectCommandType="StoredProcedure"
DeleteCommand="delete RequestsGL where GenLedgerID = #GenLedgerID">
<SelectParameters>
<asp:Parameter Direction="ReturnValue" Name="RETURN_VALUE" Type="Int32" />
<asp:ControlParameter ControlID="lblUserID" Name="UserID" PropertyName="Text"
Type="String" />
<asp:ControlParameter ControlID="txtRequestDate" Name="RequestDate"
PropertyName="Text" Type="DateTime" />
</SelectParameters>
</asp:SqlDataSource>
The _RowDeleted
protected void gridGL1_RowDeleted(object sender, DevExpress.Web.Data.ASPxDataDeletedEventArgs e)
{
RemainingTotal();
}
The RemainingTotal():
protected void RemainingTotal()
{
TotalGLAmount();
decimal TotalReq;
decimal TotalGL;
// Total Requested Amount
if (txtTotalAmount.Text == "")
{
TotalReq = 0.00M;
}
else
{
TotalReq = Convert.ToDecimal(txtTotalAmount.Text);
}
// Total GL Amount
if (lblTotalGLAmount.Text == "")
{
TotalGL = 0.00M;
}
else
{
TotalGL = Convert.ToDecimal(lblTotalGLAmount.Text);
}
// Total Remaining Amount
if (TotalReq != TotalGL)
{
lblRemainingAmount.Text = Convert.ToString(TotalReq - TotalGL);
lblTest.Text = Convert.ToString(TotalReq - TotalGL);
if (TotalReq > TotalGL)
{
lblRemainingAmount.ForeColor = Color.Black;
}
else if (TotalReq < TotalGL)
{
lblRemainingAmount.ForeColor = Color.Red;
}
}
else
{
if (txtTotalAmount.Text != "")
{
lblRemainingAmount.Text = "<b>EVEN!</b>";
lblRemainingAmount.ForeColor = Color.Black;
lblTest.Text = "<b>EVEN!</b>";
}
else
{
lblRemainingAmount.Text = "0.00";
lblRemainingAmount.ForeColor = Color.Black;
lblTest.Text = "0.00";
}
}
}
Check these threads:
The concept of callbacks - Why is it impossible to update external control data during a callback to another control
ASPxGridView - How to update an external control during a callback
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();
}
}