本文介绍了本机类型绑定源/如何用字符串列表填充DevExpress GridControl?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通常不会将DataSource绑定到GridControl.我通常是这样的:

I normally have no problem with binding a DataSource to a GridControl. I usually so something like this:

myGrid.DataSource = myList // BindingList<ComplexObject>
colMyStrings.FieldName = "PropertyNameOfComplexObject";

,它工作正常.我可以从网格中添加和删除行,它们将被添加到数据源"myList"中或从中删除.所以我基本上总是看到清单中的内容.

and it works fine. I can add and delete rows from the grid and they will get added to / deleted from the DataSource "myList". So I basically always see what's in my List.

但是现在我没有List<ComplexObject>,泛型类型具有属性,但是我有一个用字符串填充的列表.

But now I don't have a List<ComplexObject>, where the Generic Type has Properties, but I have a List filled with strings.

BindingList<string>

当我尝试将List绑定到我的网格时,不会得到字符串本身就是我想要绑定到列的行的内容,并且由于string没有任何属性,因此我无法填充列.FieldName与.

When I try to bind the List to my grid, it wont get that the strings themselves are what i want bound to the rows of my column and since string doesn't have any properties, there is nothing I can fill the columns .FieldName with.

我知道我可以使用包装器类来解决此问题,但是我发现这种解决方案不是很好.

I know I could use a wrapper class to solve this problem, but I don't find this solution to be very nice.

有没有办法告诉列,它应该使用的数据是对象,在这种情况下是字符串本身?

Is there a way to tell the column, that the data it should use is the Objects, in this case the strings, themselves?

这是我尝试过的事情.我以为,如果我可以制作自己的GridControl并覆盖DataSource属性的设置器,则可以制作一个内部包装器,以便使用它的任何人都不需要这样做.这种作品.我现在可以添加DataSource BindingList<string>,但是由于某些原因,我无法编辑值.我不知道为什么.

This is something I tried. I thought if I could make my own GridControl and override the setter for the DataSource Property, I could make an internal Wrapper so that anyone who uses it wont need do so. This kind of works. I can add my DataSource BindingList<string> now, but for some reason I cant edit the values. I don't know why.

这是代码:

public partial class NativeTypeGrid : DevExpress.XtraGrid.GridControl
{
    public NativeTypeGrid()
    {
        InitializeComponent();
    }

    public override object DataSource
    {
        get
        {
            return base.DataSource;
        }
        set
        {
            if (value is IBindingList)
            {
                Type GenericType;
                IBindingList myList = (IBindingList) value;
                BindingList<Wrapper> wrappedList = new BindingList<Wrapper>();
                GenericType = myList.GetType().GetGenericArguments()[0];
                if(GenericType.IsPrimitive || GenericType == typeof(string))
                {
                    for(int i = 0; i < myList.Count; i++)
                    {
                        object obj = myList[i];
                        wrappedList.Add(new Wrapper(ref obj));
                    }

                    base.DataSource = wrappedList;
                }
                else
                {
                    base.DataSource = value;
                }
            }
            else
            {
                base.DataSource = value;
            }
        }
    }

    internal class Wrapper
    {
        private object _NativeTypeProperty;

        public Wrapper()
        {
            _NativeTypeProperty = "SomeValueForInitialization";
        }

        public Wrapper(ref object nativeType)
        {
            _NativeTypeProperty = nativeType;
        }

        public object NativeTypeProperty
        {
            get { return _NativeTypeProperty; }
            set { _NativeTypeProperty = value; }
        }
    }
}

更新2

我已经弄清楚了为什么用户添加的对象不会得到任何东西.当然,这是行不通的,因为将一个Object添加到DataSource使用了basic/empty构造函数,这又意味着我的DataSource没有与原始List的连接,这就是我希望新对象成为的那个输入.我将对此进行处理,然后再次更新.

Update 2

I already figured out why it won't get any by the user added objects.Of course it doesn't work since adding an Object to the DataSource uses the basic/empty constructor, which in turn means that my DataSource doesn't have that connection to the original List, which is the one I want the new objects to be in. I will work on this and update again.

想不出更好的解决方案,因此我采用了最初的方法,并为我的字符串构建了一个包装器类.看起来有点像这样:

Couldn't think of any better solution, so I went with the initial approach and built a wrapper class for my strings. Looks a little bit like this:

class StringWrapper{
    public String MyString{ get; set;}
}

myGrid.DataSource = new BindingList<StringWrapper>();

我仍然很乐意使用另一种方法.

I would still be happy to use another approach.

推荐答案

您可以将"Column"设置为Column.FieldName.
这是示例:

You can set the "Column" as Column.FieldName.
Here is example:

var myList = new List<string>() { "String 0", "String 1", "String 2" };

myGrid.DataSource = myList;
colMyStrings.FieldName = "Column";

但是,您无法在GridView中添加或修改值,因为DevExpress团队没有正确使用这种情况,您只能删除值.

However you cannot add or modify the values in GridView, because DevExpress team does not implemented the properly usage of this case and you can only delete values.

但是,如果要使用GridControl处理列表,则需要创建列表包装器,而不是字符串包装器.为此,您可以根据文档来实现允许作为DataSourceIBindingList接口. .
这是实现IBindingList接口的简单列表包装器的示例:

But if you want to manipulate with your list by using GridControl, then you need to create list wrapper, not string wrapper. For this purpose you can implement IBindingList interface which is allowed as DataSource according to documentation.
Here is example of simple list wrapper that implements IBindingList interface:

public class ListWrapper<T> : IBindingList
{
    private IList<T> _wrappedList;

    public ListWrapper(IList<T> wrappedList)
    {
        _wrappedList = wrappedList;
    }

    #region IBindingList implementation
    #region Necessary members
    public object this[int index]
    {
        get { return new Wrapper(this, index); }//This wrapper have the Value property which is used as FieldName.
        set { Insert(index, value); }
    }

    public object AddNew()
    {
        _wrappedList.Add(default(T));

        return new Wrapper(this, Count - 1);
    }

    public void RemoveAt(int index)
    {
        _wrappedList.RemoveAt(index);
    }

    public int Count { get { return _wrappedList.Count; } }

    public IEnumerator GetEnumerator()
    {
        return new ListWrapperEnumerator(this);
    }

    private class Wrapper
    {
        private readonly ListWrapper<T> _listWrapper;
        private readonly int _index;

        public Wrapper(ListWrapper<T> listWrapper, int index)
        {
            _listWrapper = listWrapper;
            _index = index;
        }

        public T Value
        {
            get { return _listWrapper._wrappedList[_index]; }
            set { _listWrapper._wrappedList[_index] = value; }
        }
    }

    private class ListWrapperEnumerator : IEnumerator
    {
        private readonly ListWrapper<T> _listWrapper;
        private int _currentIndex;

        public ListWrapperEnumerator(ListWrapper<T> listWrapper)
        {
            _listWrapper = listWrapper;

            Reset();
        }

        public object Current
        {
            get { return _listWrapper[_currentIndex]; }
        }

        public bool MoveNext()
        {
            return _currentIndex++ < _listWrapper.Count;
        }

        public void Reset()
        {
            _currentIndex = -1;
        }
    }
    #endregion
    #region Optional members
    private bool GetValue(object value, out T result)
    {
        if (value is T)
        {
            result = (T)value;

            return true;
        }

        var wrapper = value as Wrapper<T>;
        if (wrapper != null)
        {
            result = wrapper.Value;

            return true;
        }

        result = default(T);
        return false;
    }

    public int Add(object value)
    {
        T result;

        if (GetValue(value, out result))
        {
            _wrappedList.Add(result);
            return _wrappedList.Count - 1;
        }

        return -1;
    }

    public void Clear()
    {
        _wrappedList.Clear();
    }

    public bool Contains(object value)
    {
        T result;

        if (GetValue(value, out result))
            return _wrappedList.Contains(result);

        return false;
    }

    public void CopyTo(Array array, int index)
    {
        for (int listIndex = 0; listIndex < _wrappedList.Count; listIndex++)
        {
            int arrayIndex = listIndex + index;

            if (arrayIndex >= array.Length)
                return;

            array.SetValue(_wrappedList[listIndex], arrayIndex);
        }
    }

    public int IndexOf(object value)
    {
        T result;

        if (GetValue(value, out result))
            return _wrappedList.IndexOf(result);

        return -1;
    }

    public void Insert(int index, object value)
    {
        T result;

        if (GetValue(value, out result))
            _wrappedList.Insert(index, result);
    }

    public void Remove(object value)
    {
        T result;

        if (GetValue(value, out result))
            _wrappedList.Remove(result);
    }
    #endregion
    #region Settings
    public bool AllowEdit { get { return true; } }

    public bool AllowNew { get { return true; } }

    public bool AllowRemove { get { return true; } }

    public bool IsFixedSize { get { return false; } }

    public bool IsReadOnly { get { return false; } }

    public bool SupportsChangeNotification { get { return false; } }

    public bool SupportsSearching { get { return false; } }

    public bool SupportsSorting { get { return false; } }
    #endregion
    #region Not used members
    public void AddIndex(PropertyDescriptor property) { }

    public void ApplySort(PropertyDescriptor property, ListSortDirection direction) { }

    public int Find(PropertyDescriptor property, object key) { return -1; }

    public void RemoveIndex(PropertyDescriptor property) { }

    public void RemoveSort() { }

    public bool IsSorted { get { return false; } }

    public bool IsSynchronized { get { return false; } }

    public ListSortDirection SortDirection { get { return default(ListSortDirection); } }

    public PropertyDescriptor SortProperty { get { return null; } }

    public object SyncRoot { get { return null; } }

    public event ListChangedEventHandler ListChanged;
    #endregion
    #endregion
}

您可以按以下方式使用此包装器:

You can use this wrapper as follows:

var myList = new BindingList<string>() { "String 0", "String 1", "String 2" });

myGrid.DataSource = new ListWrapper<string>(myList);
colMyStrings.FieldName = "Value";

这篇关于本机类型绑定源/如何用字符串列表填充DevExpress GridControl?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 07:16