为什么FormView中的CheckBox不保留OldValues和NewValues?

时间:2014-05-14 06:42:31

标签: asp.net checkbox formview

我的FormView,有两个复选框 - chbFFT 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>

正如您所看到的,在整个表单中删除了许多其他代码,例如文本框和标签。

我还有一些要启动的事件:ItemUpdated,ItemUpdating等。

例如,在ItemUpdated中,我根据表单的情况向人们发送电子邮件。在那里,我检查了一些数据绑定控制(文本框)以检查OldValues和NewValues以保证向人们发送电子邮件。显然,我不希望在用户点击更新时始终向人们发送电子邮件,特别是当表单中的任何内容都没有更改时。 这很好用。

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) { }
    }
}

但是当我尝试使用CheckBoxes执行相同的逻辑时,OldValues和NewValues 都不存在。两者都是NULL。我得到了可怕的Object未声明的错误。

//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) { }
}

那么为什么在FormView中使用文本框等获得OldValues和NewValues而不是CheckBoxes的处理?

在ItemUpdating中,我强制复选框具有值(NewValues),否则更新不会将复选框绑定回数据库,这是我至少可以在ItemUpdated中测试用户是否勾选方框或不是这样,我可以发送电子邮件提醒。

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;
    }
}

由于

1 个答案:

答案 0 :(得分:2)

FormView适用于双向数据绑定。你现在在这里有什么:

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

是单向绑定 - 控件能够读取值,但无法设置它。例如,考虑FormView应如何从此表达式派生此值的名称(您将在NewValues中使用的键):Convert.ToBoolean(Eval("StudentHasFFT"))?这只是一些FormView无法解析的任意代码。

对于双向数据绑定,ASP.NET使用特殊表达式:

<%# Bind("FieldName") %>

我相信您正在使用其他字段。你需要使用相同的复选框:

<asp:CheckBox ID="chbFFT" runat="server"
              Checked='<%# Bind("StudentHasFFT") %>'
              ...

请注意,要使其工作,StudentHasFFT必须是您正在使用的任何数据源中的布尔字段。例如。如果这是db数据源 - 确保将列声明为bit。