的BindingList<> (主)具有组合的BindingList<> (孩子)参考

时间:2014-06-29 09:35:45

标签: winforms c#-4.0 poco xtragrid

我的情况是BindingList<>代表具有类似性质的子集合的POCO集合,以下是两个此类POCO及其各自列表的示例代码:

DirectoryTypePoco

  public class DirectoryTypePoco : IBasePoco
  {

    public DirectoryTypePoco()
    {

    }

    public DirectoryTypePoco(Int16 directoryTypeId, String directoryImplementation, String directoryDescription, DirectoryDefinitionPocoList directoryDefinition)
    {
      DirectoryTypeId = directoryTypeId;
      DirectoryImplementation = directoryImplementation;
      DirectoryDescription = directoryDescription;
      DirectoryDefinition = directoryDefinition;
    }

    public Int16 DirectoryTypeId { get; set; }
    public String DirectoryImplementation { get; set; }
    public String DirectoryDescription { get; set; }
    public DirectoryDefinitionPocoList DirectoryDefinition { get; set; }

    public object GenerateEntity(GenericRepository repository, params object[] parameters)
    {
      var lastMaxEntityId = repository.GetQuery<DirectoryType>().Select(select => @select.DirectoryTypeId).DefaultIfEmpty().Max();

      var newEntity = new DirectoryType
      {
        DirectoryTypeId = (short)(lastMaxEntityId + 1),
        DirectoryImplementation = this.DirectoryImplementation,
        DirectoryDescription = this.DirectoryDescription
      };

      return newEntity;
    }

  }

BindingList<DirectoryTypePoco>

  public class DirectoryTypePocoList : BindingList<DirectoryTypePoco>
  {

    public DirectoryTypePocoList()
    {
      using (var repository = new GenericRepository(new PWRDbContext()))
      {
        var query = repository.GetQuery<DirectoryType>();

        foreach (var r in query)
        {
          Add(new DirectoryTypePoco(r.DirectoryTypeId, r.DirectoryImplementation, r.DirectoryDescription, new DirectoryDefinitionPocoList(r.DirectoryTypeId)));
        }
      }
    }

    public DirectoryTypePocoList(short directoryTypeId)
    {
      using (var repository = new GenericRepository(new PWRDbContext()))
      {
        var query = repository.GetQuery<DirectoryType>(where => where.DirectoryTypeId == directoryTypeId);

        foreach (var r in query)
        {
          Add(new DirectoryTypePoco(r.DirectoryTypeId, r.DirectoryImplementation, r.DirectoryDescription, new DirectoryDefinitionPocoList(r.DirectoryTypeId)));
        }
      }
    }
  }

第二个对象:DirectoryDefinitionPoco

  public class DirectoryDefinitionPoco : IBasePoco
  {

    public DirectoryDefinitionPoco()
    {

    }

    public DirectoryDefinitionPoco(Int16 directoryTypeId, Byte parameterId, String parameterName, String parameterValidation, Boolean encryptionRequired, PocoChangeType changeType = PocoChangeType.None)
    {
      DirectoryTypeId = directoryTypeId;
      ParameterId = parameterId;
      ParameterName = parameterName;
      ParameterDescription = parameterName;
      ParameterRequired = false;
      ParameterValidation = parameterValidation;
      EncryptionRequired = encryptionRequired;
    }

    public Int16 DirectoryTypeId { get; set; }
    public Byte ParameterId { get; set; }
    public String ParameterName { get; set; }
    public String ParameterDescription { get; set; }
    public String ParameterValidation { get; set; }
    public Boolean ParameterRequired { get; set; }
    public Boolean EncryptionRequired { get; set; }    

    public object GenerateEntity(GenericRepository repository, params object[] parameters)
    {
      var masterId = (short) parameters[0];
      var lastMaxEntityId = repository.GetQuery<DirectoryDefinition>(where => where.DirectoryTypeId == masterId).Select(select => @select.ParameterId).DefaultIfEmpty().Max();

      var newEntity = new DirectoryDefinition
      {
        DirectoryTypeId = (short)parameters[0],
        ParameterId = (byte)(lastMaxEntityId + 1),
        ParameterName = this.ParameterName,
        ParameterDescription = this.ParameterDescription,
        ParameterValidation = this.ParameterValidation,
        ParameterRequired = this.ParameterRequired,
        EncryptionRequired = this.EncryptionRequired
      };

      return newEntity;
    }
  }

BindingList<DirectoryDefinitionPoco>

  public class DirectoryDefinitionPocoList : BindingList<DirectoryDefinitionPoco>
  {
    public DirectoryDefinitionPocoList(short directoryTypeId)
    {
      using (var repository = new GenericRepository(new PWRDbContext()))
      {
        var query = repository.GetQuery<DirectoryDefinition>(where => where.DirectoryTypeId == directoryTypeId);

        foreach (var r in query)
        {
          Add(new DirectoryDefinitionPoco(r.DirectoryTypeId, r.ParameterId, r.ParameterName, r.ParameterValidation, r.EncryptionRequired));
        }
      }
    }

    public List<DirectoryDefinition> GetSourceQuery()
    {
      List<DirectoryDefinition> result;

      using (var repository = new GenericRepository(new PWRDbContext()))
      {
        result =  repository.GetQuery<DirectoryDefinition>().ToList();
      }

      return result;
    }

    public List<DirectoryDefinition> GetSourceQuery(short directoryTypeId)
    {
      List<DirectoryDefinition> result;

      using (var repository = new GenericRepository(new PWRDbContext()))
      {
        result = repository.GetQuery<DirectoryDefinition>(where => where.DirectoryTypeId == directoryTypeId).ToList();
      }

      return result;
    }
  }

在表单上,​​我通过BindingSource组件将数据加载到网格中。子行正确添加,数据有效。

Sample application

以下是问题:我可以添加新的DirectoryTypePoco但是当尝试在代码中添加DirectoryDefinitionPoco时,{{1我得到的对象对于它的父对象是零。在上图中,DirectoryDefinitionPocoTest5.dll234 DirectoryTypePoco,除了我创建的新项目之外,其下的所有子项都可以。在这种情况下,我想做些什么来确保我有Master-Child关系?

1 个答案:

答案 0 :(得分:0)

确定。看来在我的设计中我应该注意到两件事。

  • 个别孩子Poco需要通过参考知道父Poco。
  • DevExpress Grid 具有方法,允许在子视图的特定行中检索附加数据到父行。

第一部分很简单:在父poco类型的子poco中添加一个新属性。

然而,在我的情况下,这并没有解决我的问题,因为当我在网格上直观地添加新行时,默认构造函数被调用并且它不带参数,因此父poco引用将保持 NULL 和Ids(数字)将默认为 0

第二点帮助完全解决了我的问题。我能够为XtraGrid的GridView构建一个扩展方法,如下所示:

public static class DevExpressGridHelper
{
  public static IBasePoco GetPocoFromSelectedRow(this BaseView view)
  {
    return (IBasePoco)view.GetRow(((GridView)view).FocusedRowHandle);
  }

  public static IBasePoco GetParentPocoFromSelectedRow(this GridView view)
  {
    if (view.ParentView !=null)
    {
      // return (IBasePoco)(view.ParentView).GetRow(((GridView)(view.ParentView)).FocusedRowHandle);  
      return (IBasePoco)((GridView)view.ParentView).GetFocusedRow();
    }

    return null;

  }

}

使用如下:

private void GridMain_Level_1_RowUpdated(object sender, RowObjectEventArgs e)
{
  var view = sender as GridView;

  if (view == null)
  {
    return;
  }

  var pocoObject = e.Row as DirectoryDefinitionPoco;

  if (pocoObject == null)
  {
    return;
  }

  var parentPocoObject = view.GetParentPocoFromSelectedRow();

  if (parentPocoObject == null)
  {
    return;
  }

  if (view.IsNewItemRow(e.RowHandle))
  {
    Create(pocoObject, parentPocoObject);
  }
  else
  {
    Update(pocoObject);
  }
}