Q:

Why does a CheckBox in a FormView not retain OldValues and NewValues?

My FormView, with two checkboxes - chbFFT and chbCertG ...
<asp:FormView HeaderText="Basic Enrolment" HeaderStyle-HorizontalAlign="Center" ID="FormView1"
    runat="server" CellPadding="4" DataKeyNames="StudentID" DataSourceID="SqlDataSource1"
    ForeColor="#333333" Style="width: 100%" OnItemUpdated="FormView1_ItemUpdated" OnItemUpdating="FormView1_ItemUpdating" OnDataBound="FormView1_DataBound" >
    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
    <EditRowStyle BackColor="#999999" />
    <EditItemTemplate>
        <table style="width: 100%">
            <tr>
                <td>
                    <table cellpadding="4" style="width: 100%">
                    ..
                    ..
                        <tr>
                            <td valign="top" align="right">
                                FFT / Cert. Guarantee
                            </td>
                            <td style="vertical-align: top;">
                                <asp:CheckBox ID="chbFFT" runat="server" Checked='<%# Convert.ToBoolean(Eval("StudentHasFFT")) %>' Text="FFT" ToolTip="Tick this to alert WhiteRoom the student has FFT competencies. Update required to send alert." />
                                <asp:CheckBox ID="chbCertG" runat="server" Checked='<%# Convert.ToBoolean(Eval("StudentHasCertG")) %>' Text="CertG" ToolTip="Tick this to alert WhiteRoom the student has a Certificate Guarantee." />
                            </td>
                        </tr>
                   ..
                   ..
                    </table>
                </td>
            </tr>
        </table>
        <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update"
            Text="Update">
        </asp:LinkButton>
        <asp:LinkButton OnClick="EnableSideBarDisplay" ID="UpdateCancelButton" runat="server"
            CausesValidation="False" CommandName="Cancel" Text="Cancel">
        </asp:LinkButton>
    </EditItemTemplate>
    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
    <ItemTemplate>
        <table style="width: 100%">
            <tr>
                <td style="width: 50%">
                    <table cellpadding="4" style="width: 100%">
                    ..
                    ..
                        <tr>
                            <td valign="top" align="right">
                                FFT / Cert. Guarantee
                            </td>
                            <td style="vertical-align: top;">
                                <asp:CheckBox ID="chbFFT" runat="server" Enabled="false" Checked='<%# Convert.ToBoolean(Eval("StudentHasFFT")) %>' Text="FFT" ToolTip="Tick this to alert WhiteRoom that the student has at least one FFT competency. Update required to send alert." />
                                <asp:CheckBox ID="chbCertG" runat="server" Enabled="false" Checked='<%# Convert.ToBoolean(Eval("StudentHasCertG")) %>' Text="CertG" ToolTip="Tick this to alert WhiteRoom the student has a Certificate Guarantee." />
                            </td>
                        </tr>
                     ..
                     ..
                    </table>
                </td>
            </tr>
        </table>
        <asp:LinkButton OnClick="DisableSideBarDisplay" ID="lnkbttnEditItems" runat="server"
            CausesValidation="False" CommandName="Edit" Text="Edit" OnInit="SetVisibility">
        </asp:LinkButton>
    </ItemTemplate>
    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" HorizontalAlign="Center" />
</asp:FormView>

As you can see there was a lot of other code removed such as textboxes and labels throughout the form.
I also have some events to fireup: ItemUpdated, ItemUpdating, etc.
In ItemUpdated for example, I email people based on situations with the form. In there I have checks on some databound countrols (the textboxes) to check for OldValues and NewValues to warrant emailing people. Obviously, I don't want to email people all the time the user hits UPDATE especially when nothing in the form has changed. This works fine.
protected void FormView1_ItemUpdated(object sender, FormViewUpdatedEventArgs e)
{
    //Email accounts when student withdrawn
    if (e.NewValues["StudentEnrolmentStatus"].ToString() == "20" && e.OldValues["StudentEnrolmentStatus"].ToString() != "20")
    {
        //blahblahblah
        //...

        SmtpClient smtpClient = new SmtpClient();
        try
        {
            smtpClient.Send(message);
        }
        catch (Exception ex) { }
    }
}

But when I try and do the same logic with the CheckBoxes, both OldValues and NewValues do not exist. Both are NULL. And I get the dreaded Object not declared error.
//email WhiteRoom when student has been flagged FFT or CertG
if (e.NewValues["StudentHasFFT"].ToString() == "1" || !e.OldValues["StudentHasFFT"].ToString() == "1")
    {
    //blahblahblah
    //...

    SmtpClient smtpClient = new SmtpClient();
    try
    {
        smtpClient.Send(message);
    }
    catch (Exception ex) { }
}

So why in a FormView do textboxes, etc get the treatment of having OldValues and NewValues but not CheckBoxes?
In ItemUpdating, I am forcing the checkboxes to have values (NewValues), otherwise the update will not bind the checkbox back to the database, and it's the only way I can at least test in ItemUpdated whether the user ticked the boxes or not so I can send an email alert.
protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
    //convert a tickbox to '1' or '0' and not null
    FormView fv = sender as FormView;
    if (fv != null)
    {
        CheckBox chbFFT = fv.FindControl("chbFFT") as CheckBox;
        if (chbFFT != null)
            e.NewValues["StudentHasFFT"] = chbFFT.Checked ? 1 : 0;
        CheckBox chbCertG = fv.FindControl("chbCertG") as CheckBox;
        if (chbCertG != null)
            e.NewValues["StudentHasCertG"] = chbCertG.Checked ? 1 : 0;
    }
}

Thanks

A:

FormView works with 2-way data binding. What you currently have here:
<asp:CheckBox ID="chbFFT" runat="server"
              Checked='<%# Convert.ToBoolean(Eval("StudentHasFFT")) %>'
              ...

is a one way binding - control is able to read the value, but cannot set it. For example, think about how FormView is supposed to derive the name of this value (key that you will use in NewValues) from this expression: Convert.ToBoolean(Eval("StudentHasFFT"))? This is just some arbitrary code, which FormView is not able to parse.
For two-way data binding ASP.NET uses special expression:
<%# Bind("FieldName") %>

which I am sure you are using other fields. You need to use the same for checkboxes:
<asp:CheckBox ID="chbFFT" runat="server"
              Checked='<%# Bind("StudentHasFFT") %>'
              ...

Note that for this to work StudentHasFFT has to be a boolean field in whatever data source you are using. E.g. if this is db data source - make sure column is declared as bit.

