2012-03-06 51 views
2

我将一些纸质表单转换为Web表单,我的一个要求是有一个Yes/No组的复选框,如果没有选择,也可以跟踪。所以我不能只使用绑定到Sql Server中的一个位字段的CheckBox,因为它不会跟踪用户是否忽略了该字段。自定义控件的绑定工作在GridView中但不在FormView中

为了解决我的问题,我将两个复选框包装到一个ASCX控件中。然后我在ASCX控件中创建了一个公共Checked属性。从这个属性中,如果选中了真正的复选框,则返回“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

您是否尝试过使用可空的布尔类型(bool?)。这将给出三个选项,然后您可以检查hasvalue是否将位列设置为DBNull。 – 2012-03-06 21:33:50

+0

@JonRaynor - 我尝试了可空的bool类型,并从数据库中读取NULL值并发送给我的控件,如上所示,站点崩溃。 – 2012-03-07 16:28:36

+0

当读取数据时,您需要一些代码来检查数据库中的值是否为空,例如if(record [“YesNoFlag”] == DBNull.Value then //将可为空的类型设置为不具有值。 .. – 2012-03-07 18:58:58

回答

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 

与该改变存储过程我没”我不得不对之前发布的代码做任何修改。

2

您是否想过使用nullable types

然后,你可以有更简单的代码,它会更好地匹配数据库,因为SQL Server有一个可空的位类型。像这样的东西应该工作:基于关你说的错误没有发生以上你的代码,我敢打赌,有一些问题,你从字符串转换为int插入到数据库所在的

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

。再次,切换到上面的代码应该可以解决这个问题。

+0

+ 1阅读我的想法 – 2012-03-06 21:34:23

+0

我没有考虑过它b/c我不熟悉可为空的类型。我的代码出现编译错误,但我会处理它并报告回来。谢谢 – 2012-03-06 21:39:46

+0

贾斯汀C - 尝试我的修改后的代码。我犯了两个错误,因为我输入得太快。修改后的代码应该更好。移动到setChecked的原因是您需要将字符串转换为布尔值,除非您还想让get返回不理想的字符串,否则您无法在属性上执行此操作。 – 2012-03-06 21:45:15