[英]Native type binding source / How to fill a DevExpress GridControl with a List of strings?
我通常將 DataSource 綁定到 GridControl 沒有問題。 我通常是這樣的:
myGrid.DataSource = myList // BindingList<ComplexObject>
colMyStrings.FieldName = "PropertyNameOfComplexObject";
它工作正常。 我可以從網格中添加和刪除行,它們將被添加到數據源“myList”中/從數據源“myList”中刪除。 所以我基本上總是看到我的列表中的內容。
但是現在我沒有List<ComplexObject>
,其中通用類型具有屬性,但我有一個填充字符串的 List 。
BindingList<string>
當我嘗試將 List 綁定到我的網格時,它不會得到字符串本身就是我想要綁定到我的列的行的內容,並且由於字符串沒有任何屬性,因此我無法填充列.FieldName
.
我知道我可以使用包裝類來解決這個問題,但我覺得這個解決方案不是很好。
有沒有辦法告訴列,它應該使用的數據是對象,在這種情況下是字符串本身?
這是我嘗試過的。 我想如果我可以創建自己的 GridControl 並覆蓋 DataSource 屬性的 setter,我可以創建一個內部 Wrapper,這樣任何使用它的人都不需要這樣做。 這種作品。 我現在可以添加我的DataSource BindingList<string>
,但由於某種原因我無法編輯這些值。 我不知道為什么。
這是代碼:
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; }
}
}
}
我已經弄清楚為什么用戶添加的對象不會得到任何東西。 當然它不起作用,因為向數據源添加對象使用基本/空構造函數,這反過來意味着我的數據源沒有與原始列表的連接,這是我希望新對象成為的那個in. 我會處理這個並再次更新。
想不出更好的解決方案,所以我采用了最初的方法並為我的字符串構建了一個包裝類。 看起來有點像這樣:
class StringWrapper{
public String MyString{ get; set;}
}
myGrid.DataSource = new BindingList<StringWrapper>();
我仍然很樂意使用另一種方法。
您可以將"Column"
設置為Column.FieldName
。
這是示例:
var myList = new List<string>() { "String 0", "String 1", "String 2" };
myGrid.DataSource = myList;
colMyStrings.FieldName = "Column";
但是您不能在GridView
添加或修改值,因為 DevExpress 團隊沒有實現這種情況的正確使用,您只能刪除值。
但是,如果您想使用GridControl
操作您的列表,那么您需要創建列表包裝器,而不是字符串包裝器。 為此,您可以根據文檔實現IBindingList
接口,該接口允許作為DataSource
。
這是實現IBindingList
接口的簡單列表包裝器的示例:
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
}
您可以按如下方式使用此包裝器:
var myList = new BindingList<string>() { "String 0", "String 1", "String 2" });
myGrid.DataSource = new ListWrapper<string>(myList);
colMyStrings.FieldName = "Value";
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.