.net – 如何将CheckBox绑定到可以为空的bool类型的DbColumn?

Windows窗体(.NET 2.0,Visual Studio 2005 SP1)中:我有一个类型化的DataSet,其列类型为System.Boolean,可以为空,认值为dbnull.我有一个Form,包含一个CheckBox控件,我想绑定到之前的列值.

>我试图通过设计器将Checked属性绑定到列:只有当列的认值设置为True或False时,它才能正常工作.
>我试图通过设计器将CheckState属性绑定到列,并附加我自己的Format和Parse事件处理程序,但它们永远不会被调用

b.Format+=delegate(object sender,ConvertEventArgs cevent) {
    cevent.Value=DoFormat((CheckState)cevent.Value); // cf. end of the question
};
b.Parse+=delegate(object sender,ConvertEventArgs cevent) {
    cevent.Value=DoParse(cevent.Value); // cf. end of the question
};

>我试图在代码中创建一个自定义Binding实例,附加我的事件处理程序并将其添加到CheckBox绑定:事件处理程序仍然永远不会被调用

Binding b=new Binding("CheckState",_BindingSource,"MyColumn",false,DataSourceUpdateMode.OnPropertyChanged,dbnull.Value);

注意:只有来自DataSet时才接受dbnull值(这意味着从未设置过该值).但是用户应该只能通过CheckBox将值设置为True或False.

作为参考,这里是解析和格式化方法代码

internal static CheckState DoParse(object value)
{
    if ((value==null) || (value is dbnull))
        return CheckState.Indeterminate;

    bool v=Convert.ToBoolean(value);
    return (v ? CheckState.Checked : CheckState.Unchecked);
}

internal static object DoFormat(CheckState value)
{
    switch (value)
    {
    case CheckState.Checked:
        return true;
    case CheckState.Indeterminate:
        return dbnull.Value;
    case CheckState.Unchecked:
        return false;
    }

    return null;
}

解决方法

您是否尝试将CheckBox.CheckState绑定到DataColumn而不附加Parse和Format事件或搞乱绑定?

不幸的是我没有可用的Visual Studio 2005实例,但是我在Visual Studio 2008中组装了一个快速表单,它完全符合您的指定:

As a note : a dbnull value is acceptable only when coming from the DataSet (it means the value has never been set). But the user should only be able to set the value to True or False via the CheckBox.

我可能是Parse,Format或Binding阻碍你或者可能是Windows Forms在2008年的表现与2005年不同

8月18日更新:
它也可以通过设计器和代码在Visual Studio 2005上运行.
这是演示它工作的代码

using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        DataTable table = new DataTable();
        public Form1() {
            InitializeComponent();

            //Creates the table structure
            table.Columns.Add("Name",typeof(string));
            table.Columns.Add("MyColumn",typeof(bool));

            //Populates the table with some stuff
            for (int i = 0; i &lt 5; i++) {
                table.Rows.Add(i.ToString());
            }

            //Creates the controls and puts them on the form.
            TextBox textBox = new TextBox();
            textBox.Location = new Point(10,10);
            textBox.DataBindings.Add("Text",table,"Name");

            CheckBox checkBox = new CheckBox();
            checkBox.Left = textBox.Left;
            checkBox.Top = textBox.Bottom + 10;

            //Without true on the last argument,it will not work properly.
            checkBox.DataBindings.Add("CheckState",true);

            Button prevIoUs = new Button();
            prevIoUs.Text = "";
            next.Top = prevIoUs.Top;
            next.Left = prevIoUs.Right + 5;
            next.Click += new EventHandler(next_Click);

            this.Controls.AddRange(new Control[] { textBox,checkBox,prevIoUs,next });
        }

        void next_Click(object sender,EventArgs e) {
            this.BindingContext[this.table].Position++;
        }

        void prevIoUs_Click(object sender,EventArgs e) {
            this.BindingContext[this.table].Position--;
        }
    }
}

8月23日更新:

为什么会这样

Binding有一个名为FormatObject的私有方法,它负责获取适合在控件上显示的来自数据源的值的表示.

启用格式化后,Binding.FormatObject()将通过代码路径运行,该路径将调用您对Binding.Format事件的最终处理程序.如果任何处理程序通过ConvertEventArgs.Value更改从数据源传播到控件的值,则将使用该值.否则,它将在名为System.Windows.Forms.Formatter的内部类上调用名为FormatObject的认格式化程序.

对源代码状态的评论

“真正的转换工作发生在FormatObjectInternal()中”

FormatObjectInternal状态的注释:

“执行一些特殊情况转换(例如布尔到CheckState)”

在FormatObjectInternal内部,它检查来自数据源的值是否为null或dbnull,如果是这种情况,它会检查绑定的属性的类型是否为CheckState.如果是这种情况,则返回CheckState.Indeterminate.

正如您所看到的,这是一个常见的情况,它在Windows Forms 1.x上无效.幸运的是,它固定在2.0及更高版本.

相关文章

vue阻止冒泡事件 阻止点击事件的执行 <div @click=&a...
尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用...
后台我拿的数据是这样的格式: [ {id:1 , parentId: 0, name:...
JAVA下载文件防重复点击,防止多次下载请求,Cookie方式快速简...
Mip是什么意思以及作用有哪些