我正在将一些纸质表单转换为Web表单,我的一个要求是具有“是/否”组复选框,这些复选框也可以跟踪是否未进行选择。所以我不能只使用绑定到Sql Server中的位字段的单个CheckBox,因为它不会跟踪用户是否忽略该字段。
为了解决我的问题,我将两个复选框包装到ASCX控件中。然后我在ASCX控件中创建了一个公共Checked属性。如果选中了true复选框,则返回“True”,如果选中false复选框,则返回“False”,如果未选中复选框,则返回空字符串。
当我将此控件放在GridView中并使用GridView SqlDataSource将其绑定到位字段时,一切都很完美。当我在FormView中绑定相同的控件时,虽然FormView的更新将未触摸的控件设置为False。我逐步完成了我的控制逻辑,它正确地传递了空字符串,所以看起来FormView在将值发送到存储过程之前覆盖了该值。
有没有办法在FormView中使这个工作,或者我将不得不重构使用类似int字段的东西来跟踪三个选项:0 =没有选择,1 =真,2 =假,或者某事像那样?我已经在下面提供了我的ASCX控件的代码供参考。
public partial class controls_yesNoCheck : System.Web.UI.UserControl
{
public string Checked
{
get
{
if (ckbNo.Checked)
return "false";
if (ckbYes.Checked)
return "true";
else
return "";
}
set
{
if (value == "")
{
ckbNo.Checked = false;
ckbYes.Checked = false;
}
else if (value == "True" || value == "true")
{
ckbYes.Checked = true;
ckbNo.Checked = false;
}
else
{
ckbNo.Checked = true;
ckbYes.Checked = false;
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void noChecked(object sender, EventArgs e)
{
ckbYes.Checked = false;
}
protected void yesChecked(object sender, EventArgs e)
{
ckbNo.Checked = false;
}
}
编辑: 控件的前端看起来如此,我将CheckChanged方法从前一个代码块中删除,因为它们的功能不会影响这个问题。
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="yesNoCheck.ascx.cs" Inherits="controls_yesNoCheck" %>
<asp:CheckBox ID="ckbYes" runat="server" Text="Yes" AutoPostBack="true" OnCheckedChanged="yesChecked" />
<asp:CheckBox ID="ckbNo" runat="server" Text="No" AutoPostBack="true" OnCheckedChanged="noChecked" />
答案 0 :(得分:2)
您是否考虑过使用nullable types?
然后,您可以拥有更简单的代码,并且它可以更好地匹配DB,因为SQL Server具有可空的位类型。这样的事情应该有效:
public bool? Checked {get; private set;}
public void setChecked(String value)
{
if (value == "")
_checked = null;
else if (value.ToLower() == "true")
_checked = true;
else
_checked = false;
}
根据您所说的错误未发生的地方以及上面的代码,我敢打赌,从string转换为int以插入数据库时存在一些问题。再次,切换到上面的代码应解决该问题。
答案 1 :(得分:0)
对于任何可能在以后偶然发现的人,@randomben和@jonraynot可能会咆哮“最佳实践”树,但我能够通过更改我的存储过程来解决我的问题。
它可能不是有史以来最好的解决方案,但在这里。我将更新存储过程中的参数从位字段更改为nvarchar(5),然后使用以下CASE语句(简化以获得指向)
UPDATE table_name
SET bit_column_name = CASE
WHEN @bit_column_name = 'True' THEN 'True'
WHEN @bit_column_name = 'False' THEN 'False'
ELSE NULL
END
通过对存储过程的更改,我不必对之前发布的代码进行任何更改。