在我们的项目中数据库中所有的bool值都是用Char(1)来记录的,‘T‘为真 'F’则为假。有意思的是DataGridView上的CheckBoxColumn有TrueValue和FalseValue属性,如果你想用三态还有一个Indeterminate属性。这样只需要将TrueValue设置为’T’将FalseValue设置为‘F’就可以轻松绑定。但是CheckBox控件就没有这些属性,只能通过能隐式转换为bool值的属性绑定(bool类型,字符串“True”和”False”),否则抛出不是有效的布尔值的异常。那么如何将’T’转化为true将’F’转化为false来绑定到CheckBox上呢?

方法一、在Business类上加bool型的属性,或建VO类。将原有属性封装为bool型。这种方法可行。但是需要一定的工作量,而且在类中加入一些重复的属性(只是类型不同)感觉不爽。

方法二、使用Binding的Format和Parse事件。这个是我推荐的方法,其实微软已经想到了绑定属性与被绑定属性可能要存在类型转换的问题,这两个事件就是为这种情况而预留的接口。

关于这两个事件的官方文档可以参考:http://msdn.microsoft.com/zh-cn/library/system.windows.forms.binding.parse.aspx

Format是控件绑定时和数据源的值发生变化时调用,Parse是离开焦点时调用。其实Parse掉用时就是改变数据源时,因此Parse调用完就会调用Format.

Format顾名思义就是转化为可以显示的值,那么CheckBox就是用bool值显示。在我这个情况中就是由string转化为bool。Parse就是解析为数据源的所需要的值,在我这个情况就是由bool转化为string。但是考虑到三态的可能因此我并不是进行string与bool的转化。而是string与CheckState的转化。

/// 
/// Binds the CheckBox
/// 
/// Binding Source
/// The Combo Box
/// The binding field name
protected void BindingCheckBox(BindingSource source, CheckBox checkBox, string bindingField)
{
    Binding binding = checkBox.DataBindings["CheckState"];
    if (binding != null)
    {
        checkBox.DataBindings.Remove(binding);
    }
    Binding checkBoxBinding = new Binding("CheckState", source, bindingField, true, DataSourceUpdateMode.OnPropertyChanged);
    checkBoxBinding.Format += BindingCheckBox_Format;
    checkBoxBinding.Parse += BindingCheckBox_Parse;
    checkBox.DataBindings.Add(checkBoxBinding);
}
/// 
/// Format event for checkBox binding
/// 
/// The source of the event. Here is Binding.
/// Provides data for the System.Windows.Forms.Binding.Format and System.Windows.Forms.Binding.Parse events.
void BindingCheckBox_Format(object sender, ConvertEventArgs e)
{
    if (e.DesiredType == typeof(CheckState))
    {
        if (e.Value != null && e.Value.ToString() == "T")
        {
            e.Value = CheckState.Checked;
        }
        else if (e.Value != null && e.Value.ToString() == "M")
        {
            e.Value = CheckState.Indeterminate;
        }
        else
        {
            e.Value = CheckState.Unchecked;
        }
    }
}
/// 
/// Parse event for checkBox binding
/// 
/// The source of the event. Here is Binding.
/// Provides data for the System.Windows.Forms.Binding.Format and System.Windows.Forms.Binding.Parse events.
void BindingCheckBox_Parse(object sender, ConvertEventArgs e)
{
    if (e.DesiredType == typeof(string))
    {
        switch ((CheckState)e.Value)
        {
            case CheckState.Checked:
                e.Value = "T";
                break;
            case CheckState.Indeterminate:
                e.Value = "M";
                break;
            default:
                e.Value = "F";
                break;
        }
    }
}

这样我们就可以使用这个方法来将CheckBox与绑定源进行绑定了。当然你的绑定源也可以是一般的对象。在这里"M"来做不确定值,这是项目的约定。这里我省去了判断CheckBox是否是允许三态,而是判断绑定的值是否是不确定态,如果是不确定态则认为CheckBox就是允许三态,否则非真即假。