WinForms将通用列表可检查业务对象绑定到网格

WinForms将通用列表可检查业务对象绑定到网格,winforms,binding,grid,Winforms,Binding,Grid,我们都喜欢与WPF绑定是多么容易。现在我又开始使用Winforms,我正在寻找一种很好的方法将我的网格绑定到一个可检查的BusinessObject列表(我坚持使用Winforms的BindingList)。因此,我基本上只是向我的业务对象添加了一个可检查项 我使用的是一个网格,因为用户将在其中编辑多个列(在本场景中,业务对象的名称和描述),并将新对象添加到网格中并从中删除。选中列表框不适合此用途,因为我要编辑列 为此,我使用.NET4 我基本上希望减少场景中的UI代码量,因此我使用基于视图模型

我们都喜欢与WPF绑定是多么容易。现在我又开始使用Winforms,我正在寻找一种很好的方法将我的网格绑定到一个可检查的BusinessObject列表(我坚持使用Winforms的BindingList)。因此,我基本上只是向我的业务对象添加了一个可检查项

我使用的是一个网格,因为用户将在其中编辑多个列(在本场景中,业务对象的名称和描述),并将新对象添加到网格中并从中删除。选中列表框不适合此用途,因为我要编辑列

为此,我使用.NET4

我基本上希望减少场景中的UI代码量,因此我使用基于视图模型的方法来填充列表。我希望用户能够选中每个业务对象属性旁边的复选框

当然,我可以使用继承,但是如果我想对许多业务对象应用相同的机制(有许多不同的屏幕,您可以在其中为不同的业务对象检查列表中的项目)。也许这将是一条路,但我有我的怀疑

现在取决于网格的选择——我使用的是基础设施——希望功能在概念上非常相似

我考虑将业务对象包装到一个可检查的泛型类中:

using System;
using System.Collections.Generic;

public class Checkable<T> : ModelBase
{
    public Checkable(T value)
    {
        _value = value;
    }

    private T _value;
    public T Value
    {
        get
        {
            return _value;
        }
        set
        {
            if (!EqualityComparer<T>.Default.Equals(_value, value))
            {
                _value = value;
                OnPropertyChanged("Value");
            }
        }
    }

    private bool _checked;
    public bool Checked
    {
        get { return _checked; }
        set 
        {
            if (_checked != value)
            {
                _checked = value;
                OnPropertyChanged("Checked");
            }
        }
    }

}
其中ModelBase仅实现INotifyPropertyChanged:

public abstract class ModelBase : INotifyPropertyChanged, IDisposable
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    protected bool SetProperty<T>(ref T field, T value, string propertyName = null)
    {
        if (object.Equals(field, value)) { return false; }

        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            PropertyChanged = null;
        }
    }
}
公共抽象类模型库:INotifyPropertyChanged,IDisposable
{
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
受保护的bool SetProperty(参考T字段,T值,字符串propertyName=null)
{
if(object.Equals(field,value)){return false;}
字段=值;
OnPropertyChanged(propertyName);
返回true;
}
公共空间处置()
{
处置(真实);
总干事(本);
}
公共虚拟无效处置(bool处置)
{
如果(处置)
{
PropertyChanged=null;
}
}
}
因此,对于我的网格数据源,我可能会定义:

// in view model
var datasource = new BindingList<Checkable<BusinessObject>>();
... populate list


grid.DataSource = viewmodel.DataSource;
//视图中的模型
var datasource=newbindingslist();
... 填充列表
grid.DataSource=viewmodel.DataSource;
因此,我的场景当然会失败,因为Value是BusinessObject引用,它具有我想要绑定的属性,Checked是我想要绑定的复选框的属性

我正试图用一些关于这方面的想法来启动旧的灰质。我真的不喜欢编写代码来定义网格列。但是,Infragistics网格在设计时可以直接将数据绑定到BusinessObject。可以添加一个未绑定的列(我的场景中的复选框)并手动处理项目的选中/取消选中(我可能必须这样做)


我想知道我是否错过了Winform绑定的任何巧妙技巧,因为多年前Linq和Entity Framework出现时,我就错过了它们。

解决方案:放置一个
ElementHost
并使用WPF来完成它。winforms是无用的。
// in view model
var datasource = new BindingList<Checkable<BusinessObject>>();
... populate list


grid.DataSource = viewmodel.DataSource;