将HQL查询结果绑定到DevExpress GridControl

时间:2012-11-20 08:55:56

标签: nhibernate data-binding devexpress hql

我想将HQL个查询结果与DevExpress GridControl绑定。

无法在编译时预测查询定义。它基于用户定义的配置设置构建。

var queryResults = GetSession().CreateQuery(PrepereHQLQuery()).List();
gridControl1.DataSource = queryResults;

假设PrepareHQLQuery返回select col1, col2 from MyTable我希望得到这样的内容:

enter image description here

而不是:

I have no concept how to force DataGrid to show data from array of object

是否存在任何方法来配置GridView列以直接从List的{​​{1}}显示数据?

由于HQL查询的不可预测性,我还想避免使用Object[]等中间对象。

1 个答案:

答案 0 :(得分:1)

您可以创建封装HQL查询结果的包装类,该结果实现IList和ITypedList接口。此方法允许您将HQL查询结果用作XtraGrid的数据源 以下是您可以调整的小样本:

IList<object[]> queryResult = new List<object[]>{
    new object[]{ "a", 11 },
    new object[]{ "b", 22 }
};
gridControl1.DataSource = new QueryWrapper(queryResult);
//...
public class QueryWrapper : IList, ITypedList {
    class ColumnDescriptor : PropertyDescriptor {
        int index;
        Type elementType;
        public ColumnDescriptor(string name, int index, Type elementType)
            : base(name, null) {
            this.index = index;
            this.elementType = elementType;
        }
        public override Type ComponentType {
            get { return typeof(RowDescriptor); }
        }
        public override bool IsReadOnly {
            get { return false; }
        }
        public override Type PropertyType {
            get { return elementType; }
        }
        public override object GetValue(object component) {
            return ((RowDescriptor)component).GetValue(index);
        }
        public override void SetValue(object component, object value) {
            ((RowDescriptor)component).SetValue(index, value);
        }
        public override bool CanResetValue(object component) { return false; }
        public override void ResetValue(object component) { }
        public override bool ShouldSerializeValue(object component) { return false; }
    }
    class RowDescriptor : CustomTypeDescriptor {
        QueryWrapper owner;
        object[] rowObjects;
        public RowDescriptor(QueryWrapper owner, object[] rowObjects) {
            this.rowObjects = rowObjects;
            this.owner = owner;
        }
        public object GetValue(int index) {
            return rowObjects[index];
        }
        public void SetValue(int index, object value) {
            rowObjects[index] = value;
        }
        public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) {
            return owner.pdc;
        }
    }
    IList<object[]> query;
    List<RowDescriptor> list;
    public QueryWrapper(IList<object[]> query) {
        this.query = query;
        list = new List<RowDescriptor>(query.Count);
        for(int i = 0; i < query.Count; i++)
            list.Add(new RowDescriptor(this, query[i]));
    }
    #region IList Members
    int IList.Add(object value) {
        throw new NotSupportedException();
    }
    void IList.Clear() {
        throw new NotSupportedException();
    }
    bool IList.Contains(object value) {
        return value is RowDescriptor && list.Contains((RowDescriptor)value);
    }
    int IList.IndexOf(object value) {
        return (value is RowDescriptor) ? list.IndexOf((RowDescriptor)value) : -1;
    }
    void IList.Insert(int index, object value) {
        throw new NotSupportedException();
    }
    bool IList.IsFixedSize {
        get { return true; }
    }
    bool IList.IsReadOnly {
        get { return true; }
    }
    void IList.Remove(object value) {
        throw new NotSupportedException();
    }
    void IList.RemoveAt(int index) {
        throw new NotSupportedException();
    }
    object IList.this[int index] {
        get { return list[index]; }
        set { throw new NotSupportedException(); }
    }
    #endregion
    #region ICollection Members
    void ICollection.CopyTo(Array array, int index) {
        if(array is RowDescriptor[]) list.CopyTo((RowDescriptor[])array, index);
    }
    int ICollection.Count {
        get { return list.Count; }
    }
    bool ICollection.IsSynchronized {
        get { return false; }
    }
    object ICollection.SyncRoot {
        get { return this; }
    }
    #endregion
    #region IEnumerable Members
    IEnumerator IEnumerable.GetEnumerator() {
        return list.GetEnumerator();
    }
    #endregion
    #region ITypedList Members
    PropertyDescriptorCollection pdc;
    PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) {
        if(pdc == null) {
            if(query.Count > 0) {
                PropertyDescriptor[] pd = new PropertyDescriptor[query[0].Length];
                for(int i = 0; i < pd.Length; i++)
                    pd[i] = new ColumnDescriptor("Column" + i, i, query[0][i].GetType());
                pdc = new PropertyDescriptorCollection(pd);
            }
            else pdc = new PropertyDescriptorCollection(new PropertyDescriptor[] { });
        }
        return pdc;
    }
    string ITypedList.GetListName(PropertyDescriptor[] listAccessors) { return string.Empty; }
    #endregion
}