2

I have been programming for many years, about 10 in an older version of .NET, as a result I'm new to LINQ, UpdatePanels and Ajax and their way of doing things.
The following code works correctly.
The database field is defined as:

rptPriority INT NOT NULL DEFAULT(0)

A much simplified page stub which works is:

<asp:UpdatePanel ID="upReport" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <fieldset>
        <asp:DetailsView ID="dvReport" runat="server" DataSourceID="ldsReport" CssClass="reset"
            AutoGenerateRows="False" DefaultMode="Edit" Width="100%">
            <Fields>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:DynamicControl ID="Priority" runat="server" DataField="rptPriority" Mode="Edit" CssClass="general" />

etc
What I need to do is change that Dynamic Control as a textbox to a checkbox which is updatable and driven by the same data. The following gives the correct data but doesn't update.
Were I doing this using straight SQL or PROCEDURES, this would not be a big problem. (also not an option)

<asp:CheckBox ID="Priority" runat="server" Checked='<%# Convert.ToBoolean(Eval("rptPriority")) %>' />

I changed "Eval" to "Bind" and got the "ERROR CS0103: The name 'Bind' does not exist in the current context"
I suspect that the "Convert.ToBoolean" is part of the problem.
There are many pages which I've perused trying to get the info I need. Among them How to add checkbox to datagrid in vb.net , Html.CheckBox returns false if disabled, even if seleced and Checkbox server/client events , How do you know to use Container.DataItem when data binding in ASP.NET? Is there a reference? , The databind bind() function belongs to which class? not to mention about 50 more outside of stack overflow which got me to where I am now.
Edit
As per Rob's suggestion, I added the following, but couldn't get / find any way to use "DetailsViewUpdateEventArgs".

protected void dvReport_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{
    DetailsView dv = sender as DetailsView;
    CheckBox ctlPriority = dv.FindControl("Priority") as CheckBox;
    e.NewValues["rptPriority"] = ctlPriority.Checked ? 1 : 0;
}

The following is a stub from the save / update code behind.

protected void btnSave_OnCLick(object sender, EventArgs e)
{
  RadioButtonList rblReportStatus = (RadioButtonList)dvReport.FindControl("rblReportStatus");

  using (RiderReportDataContext db = new RiderReportDataContext())
  {
    Report report = null;
    Contact contact = null;
    DateTime now = DateTime.Now;
    bool doUpdate = false;

    ldsContact.Updating += (o, ea) =>
    {
      Contact original = (Contact)ea.OriginalObject;
      contact = (Contact)ea.NewObject;

      if (
        original.FirstName != contact.FirstName ||
...
        original.Email != contact.Email)
      {
        doUpdate = true;
      }

      db.Contacts.Attach(contact, original);

      ea.Cancel = true;
    };

    // force the update procedure
    dvContact.UpdateItem(true);

    ldsReport.Updating += (o, ea) =>
    {
      Report original = ea.OriginalObject as Report;
      report = ea.NewObject as Report;

      if (rblReportStatus.SelectedItem != null)
      {
        report.ReportStatusId = int.Parse(rblReportStatus.SelectedValue);
      }

      if (
        original.ReportStatusId != report.ReportStatusId ||
        original.SourceId != report.SourceId ||
...
        original.ReportTypeID != report.ReportTypeID ||
        original.rptPriority != report.rptPriority ||       // The value here doesn't change
        original.SupervisorId != report.SupervisorId)
      {
        doUpdate = true;
      }
      db.Reports.Attach(report, original);
      ea.Cancel = true;
    };

    // force the update procedure
    dvReport.UpdateItem(true);

// Other Search For Updates

    if (doUpdate)
    {
      contact.ChangedOn = now;
      report.ChangedOn = now;

      Log log = new Log();
      log.ReportId = report.Id;
      log.UserId = MembershipClass.User.Id;
      log.Text = "The report updated.";
      log.CreatedOn = now;
      report.Logs.Add(log);

      db.SubmitChanges();
    }
  }

  if (Page.IsValid)
  {
    Response.Redirect("~/default.aspx" /*table.ListActionPath */);
  }
}
Community
  • 1
  • 1
Dave
  • 1,234
  • 13
  • 24
  • 1
    Your updatepanel UpdateMode is conditional. Have you called updatepanel1.update() method on server side...?? Either make UpdateMode="Always". – Muhammad Saad Dec 20 '13 at 07:25
  • UpdateMode="Conditional" is mandatory since there are 4 update panels in the page. – Dave Dec 20 '13 at 17:57

1 Answers1

1

As you've discovered, Bind() doesn't provide an easy way to convert a data type. You will find other answers which suggest changing the type of the data you are binding to, but I understand this isn't an option in your case.

I think your best solution is to go back to one-way binding. e.g. use your existing code:

<asp:CheckBox ID="Priority" runat="server"
   Checked='<%# Convert.ToBoolean(Eval("rptPriority")) %>' />

Which will correctly set the value of the checkbox when the DetailsView is rendered, but will not provide a value for rptPriority when the details are updated. For this you'll need to add an OnItemUpdating event handler to your DetailsView, which will allow you to perform the custom conversion your need. e.g.

<asp:DetailsView ID="dvReport" runat="server"
   onitemupdating="dvReport_ItemUpdating"

And the implementation in your code-behind will look like this:-

protected void dvReport_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{
    DetailsView dv = sender as DetailsView;
    CheckBox ctlPriority = dv.FindControl("Priority") as CheckBox;
    e.NewValues["rptPriority"] = ctlPriority.Checked ? 1 : 0;
}

Hope this helps.

Rob
  • 1,472
  • 12
  • 24
  • This appears to be the correct way of doing this. I put it in and I missed something. The event is not firing. – Dave Dec 20 '13 at 20:55
  • The event should fire if you are updating (you'll need to provide a handler for ItemInserting if inserting new data. What is the name of the command on your command button? – Rob Dec 21 '13 at 13:10
  • this is an update. The insert is handled by default. – Dave Dec 22 '13 at 17:54
  • OK, great. To get to the bottom of why your event handler is not being called, can you show us the code for your command button (e.g. how is the update being invoked). – Rob Dec 22 '13 at 18:08