We're using a custom collection to handle the modifications to the items bound to the RadGridView. Everything's working as expected for all but adding items. We've found out that the Telerik grid is using IList<T> data sources as IList, which means that our custom collection have to implement it as well, in order to respect our logic.
When the grid is trying to add a new item to the collection, the grid calls the IList.Add(object item) instead of IList<T>.Add(T item).
The error message displayed by the grid is "The collection is read-only."
We would expect the grid to determine the proper type of the collection in the data source.
Current version (without IList implementation):
When the grid is trying to add a new item to the collection, the grid calls the IList.Add(object item) instead of IList<T>.Add(T item).
The error message displayed by the grid is "The collection is read-only."
We would expect the grid to determine the proper type of the collection in the data source.
Current version (without IList implementation):
public
class
EntityStateCollection<T> : IList<T> where T :
new
()
{
#region Membres
private
List<EntityState<T>> _entityStates;
private
Enumerator<T> _innerEnumerator;
public
event
EventHandler ItemAdded;
public
event
EventHandler ItemDeleted;
public
event
EventHandler ItemModified;
#endregion
#region Enumerator
[Serializable, StructLayout(LayoutKind.Sequential)]
public
struct
Enumerator<T> : IEnumerator<T>, IDisposable, IEnumerator where T :
new
()
{
private
List<EntityState<T>> list;
private
int
index;
private
T current;
internal
Enumerator(List<EntityState<T>> list)
{
this
.list = list;
this
.index = 0;
this
.current =
default
(T);
}
public
void
Dispose()
{
}
public
bool
MoveNext()
{
List<EntityState<T>> list =
this
.list;
if
(
this
.index < list.Count)
{
this
.current = list[
this
.index].InnerObject;
this
.index++;
return
true
;
}
else
{
this
.current =
default
(T);
return
false
;
}
}
public
T Current
{
get
{
return
this
.current;
}
}
object
IEnumerator.Current
{
get
{
return
this
.Current;
}
}
void
IEnumerator.Reset()
{
this
.index = 0;
this
.current =
default
(T);
}
}
#endregion Enumerator
public
EntityStateCollection()
{
_entityStates =
new
List<EntityState<T>>();
_innerEnumerator =
new
Enumerator<T>(_entityStates);
}
public
void
SetModified(T item)
{
EntityState<T> entity = _entityStates[
this
.IndexOf(item)];
if
(entity.ObjectState != State.Added)
{
entity.ObjectState = State.Modified;
this
.ItemModified(entity,
null
);
}
}
/// <summary>
/// Returns true if all T entities are at Current state.
/// </summary>
/// <returns></returns>
public
bool
IsInCurrentState()
{
for
(
int
i = 0; i < _entityStates.Count; i++)
{
if
(_entityStates[i].ObjectState != State.Current)
{
return
false
;
}
}
return
true
;
}
public
EntityState<T> GetEntityState(
int
i)
{
return
_entityStates[i];
}
/// <summary>
/// Add a list of T objects to the collection with the Current state
/// </summary>
/// <param name="lst"></param>
public
void
AddRange(List<T> lst)
{
foreach
(T item
in
lst)
{
_entityStates.Add(
new
EntityState<T>(State.Current, item));
//this.ItemAdded(_entityStates[this.IndexOf(item)], null);
}
}
#region IList<T> Membres
public
int
IndexOf(T item)
{
int
itemIndex = -1;
for
(
int
i = 0; i < _entityStates.Count; i++)
{
if
(_entityStates[i].InnerObject.Equals(item))
{
itemIndex = i;
break
;
}
}
return
itemIndex;
}
public
void
Insert(
int
index, T item)
{
_entityStates.Insert(index,
new
EntityState<T>(State.Added, item));
this
.ItemAdded(_entityStates[index],
null
);
}
public
void
RemoveAt(
int
index)
{
_entityStates[index].ObjectState = State.Deleted;
this
.ItemDeleted(_entityStates[index],
null
);
}
public
T
this
[
int
index]
{
get
{
return
_entityStates[index].InnerObject;
}
set
{
_entityStates[index].InnerObject = value;
}
}
#endregion
#region ICollection<T> Membres
public
void
Add(T item)
{
_entityStates.Add(
new
EntityState<T>(State.Added, item));
this
.ItemAdded(_entityStates[
this
.IndexOf(item)],
null
);
}
public
void
Clear()
{
_entityStates.Clear();
}
public
bool
Contains(T item)
{
for
(
int
i = 0; i < _entityStates.Count; i++)
{
if
(_entityStates[i].InnerObject.Equals(item))
{
return
true
;
}
}
return
false
;
}
public
void
CopyTo(T[] array,
int
arrayIndex)
{
throw
new
NotImplementedException();
}
public
int
Count
{
get
{
return
_entityStates.Count; }
}
public
bool
IsReadOnly
{
get
{
return
false
; }
}
public
bool
Remove(T item)
{
for
(
int
i = 0; i < _entityStates.Count; i++)
{
if
(_entityStates[i].InnerObject.Equals(item))
{
_entityStates[i].ObjectState = State.Deleted;
this
.ItemDeleted(_entityStates[i],
null
);
return
true
;
}
}
return
false
;
}
#endregion
#region IEnumerable et IEnumerable<T> Membres
public
IEnumerator<T> GetEnumerator()
{
return
this
._innerEnumerator;
}
IEnumerator IEnumerable.GetEnumerator()
{
return
this
._innerEnumerator;
}
#endregion