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

时间:2014-07-17 20:52:45

标签: winforms binding grid

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

我正在使用网格,因为用户将编辑多个列(在此方案中,业务对象上的名称和描述) - 以及向网格添加新对象并从中删除。选中列表框不适合此目的,因为我想编辑列。

为此,我使用的是.NET 4。

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

当然我可以使用继承,但是如果我想对很多业务对象应用相同的机制(有很多不同的屏幕,你可以在列表中检查不同业务对象的项目)。也许这是要走的路 - 但我有疑虑。

现在取决于网格的选择 - 我使用的是Infragistics - 这个功能在概念上非常相似。

我考虑过将业务对象包装在Checkable泛型类中:

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

}

我为这个场景编了一个业务对象:

public class BusinessObject : ModelBase
{
    public BusinessObject()
    {
    }

    public BusinessObject(RepairType repairType)
    {
        _name = repairType.Name;
        _id = repairType.Id;
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set 
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    private string _description;
    public string Description
    {
        get { return _description; }
        set 
        {
            if (description != value)
            {
                description = value;
                OnPropertyChanged("Description");
            }
        }
    }

    private int _id;
    public int Id
    {
        get { return _id; }
        set 
        {
            if (_id != value)
            {
                _id = value;
                OnPropertyChanged("Id");
            }
        }
    }
}

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

因此我可能会为我的网格数据源定义:

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


grid.DataSource = viewmodel.DataSource;

当然,我的场景在某一刻失败,因为Value是具有我想要绑定的属性的BusinessObject引用,而Checked是我也想要绑定到的复选框的属性。

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

我想知道我是否遗漏了Winform绑定的任何巧妙的技巧,这些技巧最近在多年前出现时错过了Linq和Entity Framework。

0 个答案:

没有答案
相关问题