0

So I am new to ASP.NET C# and having trouble in creating a cancel function. When the cancel function click it supposedly discard all the changes the user made inside the inputfield/dropdown and return to it's previous value before the modification has made. Is there any way to this kind of function? thanks in advance.

this is a sample scenario :enter image description here

As you can see in the photo, the user has made some modification in the selected row in gridview and when the click the cancel button, the changes should be disregarded and turn back to it's previous value .

Inputbo/dropdown part

 <table class="style2" >
    <tr>
        <td class="style3" >Department Case #</td>
        <td> <asp:TextBox ID="TextBox1" runat="server" Enabled="False" ontextchanged="btnCancel_Click"></asp:TextBox></td>
    </tr>

    <tr>
         <td class="style3">Department</td>
         <td> 
             <asp:DropDownList ID="DropDownList1" runat="server" 
                  Height="18px" Width="153px" Enabled="False" AppendDataBoundItems="true"  
                 AutoPostBack="true" DataSourceID="SqlDataSource2" 
                 DataTextField="DEPARTMENT_NAME" DataValueField="DEPARTMENT_CODE" 
                 onselectedindexchanged="DropDownList1_SelectedIndexChanged" >
                <asp:ListItem Text="--- Select ----" Value=" " />
             </asp:DropDownList>
             <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
                 ConnectionString="<%$ ConnectionStrings:*****ConnectionString %>" 
                 SelectCommand="SELECT [DEPARTMENT_CODE], [DEPARTMENT_NAME] FROM [TV_DEPTNAME]">
             </asp:SqlDataSource>
         </td>
    </tr>

    <tr> 
         <td class="style3">Charge</td>
         <td>
             <asp:DropDownList ID="DropDownList2" runat="server" 
                 Height="22px" Width="153px" Enabled="False" AppendDataBoundItems="true" 
                 AutoPostBack="true" DataSourceID="SqlDataSource3" 
                 DataTextField="OFFENSE_DESCRIPTION" DataValueField="OFFENSE_CODE" 
                 onselectedindexchanged="DropDownList1_SelectedIndexChanged" >
                 <asp:ListItem Text="--- Select ----" Value=" " />
             </asp:DropDownList>
             <asp:SqlDataSource ID="SqlDataSource3" runat="server" 
                 ConnectionString="<%$ ConnectionStrings:****ConnectionString %>" 
                 SelectCommand="SELECT [OFFENSE_CODE], [OFFENSE_DESCRIPTION] FROM [TV_OFFENSE]">
             </asp:SqlDataSource>
         </td>
    </tr>

    <tr>
        <td class="style3">Lab Case #</td>
        <td><asp:TextBox ID="TextBox4" runat="server" Enabled="False"  ontextchanged="btnCancel_Click"></asp:TextBox></td>
   </tr>

   <tr>
       <td class="style3">Incident Report Date</td>
       <td><asp:TextBox ID="TextBox5" runat="server" Enabled="False" ontextchanged="btnCancel_Click"></asp:TextBox></td>
   </tr>

</table>

button part

 <asp:TextBox ID="TextBox6" runat="server" Visible="False"></asp:TextBox>
<br />
<asp:Button ID="btnEdit" runat="server" onclick="btnEdit_Click" Text="Edit" />&nbsp;
<asp:Button ID="btnSave" runat="server" onclick="btnSave_Click" Text="Save" Enabled="false"/>&nbsp;
<asp:Button ID="btnCancel" runat="server" onclick="btnCancel_Click" Text="Cancel" Enabled="false"/>
<br />

CODE BEHIND

 protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
    {
       if (e.Row.RowType == DataControlRowType.DataRow)
       {    ///<summary> Change the mouse cursor to Hand symbol to show the user the cell is selectable</summary>
            e.Row.Attributes["onmouseover"] = "this.style.cursor='hand';this.style.textDecoration='underline';this.style.cursor='Pointer'";
            e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";

            ///<summary> Attach the click event to each cells</summary>
            e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + e.Row.RowIndex);
        }
    }

    protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
    {
        // If multiple buttons are used in a GridView control, use the
        // CommandName property to determine which button was clicked.
        if (e.CommandName == "Select")
        {
            ///<summary>
            ///Convert the row index stored in the CommandArgument
            ///property to an Integer.
            ///</summary>
            LoadData(Convert.ToInt32(e.CommandArgument));

        }
    }

    private void LoadData(int? rowNumber = null)
    {
        //if rowNumber is null use GridView1.SelectedIndex
        var index = rowNumber ?? GridView1.SelectedIndex;

        // Retrieve the row that contains the button clicked 
        // by the user from the Rows collection.
        GridViewRow row = GridView1.Rows[index];

        //Populate the input box with the value of selected row.
        GridViewRow gr = GridView1.Rows[index];
        TextBox1.Text = gr.Cells[2].Text;
        TextBox7.Text = gr.Cells[3].Text;
        TextBox8.Text = gr.Cells[4].Text;
        TextBox4.Text = gr.Cells[5].Text;
        TextBox5.Text = gr.Cells[6].Text;
        TextBox6.Text = gr.Cells[1].Text;
    }


    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {     // to set the value of the selected item in dropdown
        DropDownList1.SelectedValue = DropDownList1.SelectedItem.Value;
        DropDownList2.SelectedValue = DropDownList2.SelectedItem.Value;


    }



    protected void btnEdit_Click(object sender, EventArgs e)
    { ///<summary> Disabling/Enabling of input fields and button when a certain button is clicked</summary>
        SetEnable(true);
    }

    protected void btnSave_Click(object sender, EventArgs e)
    { ///<summary> Disabling/Enabling of input fields and button when a certain button is clicked</summary>
        SetEnable(false);

        string connetionString;
        SqlConnection cnn;

        connetionString = @"Data Source=******\MSSQL****;Initial Catalog=*****;User ID=****;Password=****";

        cnn = new SqlConnection(connetionString);

        cnn.Open();

        SqlCommand cmd = new SqlCommand("Update TV_LABCASE Set DEPARTMENT_CASE_NUMBER=@DEPARTMENT_CASE_NUMBER,DEPARTMENT_CODE=@DEPARTMENT_NAME,OFFENSE_CODE=@OFFENSE_DESCRIPTION,LAB_CASE=@LAB_CASE,OFFENSE_DATE=@OFFENSE_DATE where CASE_KEY=@CASE_KEY", cnn);
        cmd.Parameters.AddWithValue("@DEPARTMENT_CASE_NUMBER", TextBox1.Text);
        cmd.Parameters.AddWithValue("@DEPARTMENT_NAME", DropDownList1.SelectedValue);
        cmd.Parameters.AddWithValue("@OFFENSE_DESCRIPTION", DropDownList2.SelectedValue);
        cmd.Parameters.AddWithValue("@LAB_CASE", TextBox4.Text);
        cmd.Parameters.AddWithValue("@OFFENSE_DATE", TextBox5.Text);
        cmd.Parameters.AddWithValue("@CASE_KEY", TextBox6.Text);
        cmd.ExecuteNonQuery();
        cnn.Close();
        TextBox7.Text = DropDownList1.SelectedItem.Text;
        TextBox8.Text = DropDownList2.SelectedItem.Text;
        GridView1.DataBind();   

    }

    protected void btnCancel_Click(object sender, EventArgs e)
    { ///<summary> Disabling/Enabling of input fields and button when a certain button is clicked</summary>
        SetEnable(false);
        LoadData();

    }

  ///<summary> Disabling/Enabling of input fields and button when a certain button is clicked</summary>
    private void SetEnable(bool editable)
    {
        btnEdit.Enabled = !editable;
        btnSave.Enabled = editable;
        btnCancel.Enabled = editable;
        TextBox1.Enabled = editable;
        DropDownList1.Enabled = editable;
        DropDownList2.Enabled = editable;
        TextBox4.Enabled = editable;
        TextBox5.Enabled = editable;
        TextBox7.Visible = !editable;
        TextBox8.Visible = !editable;
        DropDownList1.Visible = editable;
        DropDownList2.Visible = editable;


    }

i'll just explained a while ago that i also have some issues in displaying the selected row value inside the dropdown, so instead of displaying inside the dropdown, I decided to put the value inside the textbox (which is why I included textbox 7 and 8 and they are only use to display the value of the selected row, after clicking edit button, it will be hidden and the dropdown will then be visible thus making effect of textbox turning into dropdown ) and hide and show them if i needed them. now the problem is that after I use the code you have given, the changes inside the textboxes wont save after clicking save button.

Leo Derramas
  • 95
  • 1
  • 11

1 Answers1

1

Extract code from your GridView1_RowCommand event handler into a seperate method like this:

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // If multiple buttons are used in a GridView control, use the
    // CommandName property to determine which button was clicked.
    if (e.CommandName == "Select")
    {
        //Convert the row index stored in the CommandArgument
        //property to an Integer.
        LoadData(Convert.ToInt32(e.CommandArgument));
    }
}

//int? could be written as Nullable<int>
private void LoadData(int? rowNumber = null)
{
    //if rowNumber is null use GridView1.SelectedIndex
    var index = rowNumber ?? GridView1.SelectedIndex;

    //instead of the ?? operator you can write a simple if
    var index = -1;
    if (rowNumber == null)
        index = GridView1.SelectedIndex;
    else
        index = rowNumber.Value; //Access the value property of the nullable int

    if (index == -1)
        return; //index is invalid so exit the method

    // Retrieve the row that contains the button clicked 
    // by the user from the Rows collection.
    GridViewRow row = GridView1.Rows[index];

    //Populate the input box with the value of selected row.
    GridViewRow gr = GridView1.Rows[index];
    TextBox1.Text = gr.Cells[2].Text;

    //your code would add new Items to your DropDownList everytime this method gets called
    //DropDownList1.Items.Add(gr.Cells[3].Text.ToString());
    //DropDownList2.Items.Add(gr.Cells[4].Text.ToString());

    //instead use SelectedItem property of the DropDownList, didn't know why you call .ToString() on the Text property, seemed redundant so I removed it
    //DropDownList1.SelectedItem = gr.Cells[3].Text;
    //DropDownList2.SelectedItem = gr.Cells[4].Text;

    //as was pointed out in the comments below the SelectedItem is read-only for this control
    //we need to use the following as is described here https://stackoverflow.com/questions/5121639
    DropDownList1.Items.FindByText(gr.Cells[3].Text).Selected = true;
    DropDownList2.Items.FindByText(gr.Cells[4].Text).Selected = true;


    TextBox4.Text = gr.Cells[5].Text;
    TextBox5.Text = gr.Cells[6].Text;
    TextBox6.Text = gr.Cells[1].Text;
}

And in your event handler of your cancel button call the new method, like this:

protected void CancelButton_Click(object sender, EventArgs e)
{
    LoadData();
}

FYI - the ///<summary> should only be used to desribe methods and not for in-line comments, for in-line comments stick to // comment syntax. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/summary

Rand Random
  • 7,300
  • 10
  • 40
  • 88
  • 1
    Yes, why? `int?` means I want to have a nullable integer. So, this line could be valid `int? value = null;` without the `?` it would be invalid code - see here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/using-nullable-types - the `??` is a null conditional operator so a short cut for `if (value == null) ...` see here https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator – Rand Random Oct 07 '19 at 07:38
  • thank you so much, sorry for the inconvenience because I am new at using asp.net. – Leo Derramas Oct 07 '19 at 07:46
  • 1
    No problem, glad I could help you. – Rand Random Oct 07 '19 at 07:51
  • hello i have also have one problem in displaying the selected row value inside the dropdown. I tried your code DropDownList1.SelectedItem = gr.Cells[3].Text; DropDownList2.SelectedItem = gr.Cells[4].Text; but it outputs error :Error 1 Property or indexer 'System.Web.UI.WebControls.ListControl.SelectedItem' cannot be assigned to -- it is read only , Error 2 Cannot implicitly convert type 'string' to 'System.Web.UI.WebControls.ListItem' – Leo Derramas Oct 07 '19 at 07:53
  • I have posted the problem here in stack overflow, here is the url : https://stackoverflow.com/questions/58263719/display-value-of-a-gridview-selected-row-to-dropdownlist – Leo Derramas Oct 07 '19 at 07:54
  • Have a look at: https://stackoverflow.com/questions/5121639/how-to-programmatically-set-selectedvalue-of-dropdownlist-when-it-is-bound-to-xm – Rand Random Oct 07 '19 at 09:17
  • the the code that you've answered is working on the cancel function, but when I try to test application, the save function didn't work(it is working before i tried your code) i included the save function in my list of codes above. please can you help me again, thanks in advance – Leo Derramas Oct 07 '19 at 10:27
  • Well your code to load data now writes values into `TextBoxes` (`TextBox7`, `TextBox8`) instead of `DropDownLists` but your save method still uses the `DropDownLists` (`DropDownList1`, `DropDownList2`) - you should use either or. - You should stick to the `DropDownList` since only they have the ability to store both the `ID` or `Value` (eg. `DEPARTMENT_CODE`) and the `Text` (eg. `DEPARTMENT_NAME`) – Rand Random Oct 07 '19 at 10:58
  • I mean,even if i use the dropdownlist insted of textbox7 and 8. I used the code that you have said, the cancel is working but the save doesnt. even in saving other textboxes. – Leo Derramas Oct 07 '19 at 11:07
  • Well than you have to describe "didn't work", I can only guess with the information provided and the change from `TextBoxes` to `DropDownList` is the only obvious error source since that is the only change that would effect the save method. Since the save only works if you pass the `ID` (eg. `DEPARTMENT_CODE`) it will fail when you try to save the Text (eg. `DEPARTMENT_NAME`) - in other cases the `TextBoxes` won't make an issue since it is only `Text` but your department data isn't simple `Text` it is a foreign key relation and you need to save the `ID` for this relation – Rand Random Oct 07 '19 at 11:16
  • I'll just provide the whole code behind so that you have an idea, sorry again. – Leo Derramas Oct 07 '19 at 11:21
  • Try to change the department before saving your data. Does the save work? – Rand Random Oct 07 '19 at 11:37
  • since the department and charge are dropdown in editing mode, yes they do save. only the textboxes dont save. it's kinda weird bug. – Leo Derramas Oct 07 '19 at 11:46
  • 1
    After a further look you are registering the `btnCancel_Click` event handler in the `OnTextChanged` of your `TextBoxes` with this `ontextchanged="btnCancel_Click"`, so you are basically canceling your input. – Rand Random Oct 07 '19 at 11:59
  • my fault, i didn't notice that, thank you so much again, you're great. – Leo Derramas Oct 08 '19 at 02:35