Sortable CollectionBase ?
-
Hi all, I'm working on an application, and being new to 2.0 I need some help. I have a Custom Collection which inherits CollectionBase and i'm using this as a DataGridView datasource. All is fine, apart from the Sorting does not work anymore (I used to manually add each row.) When I tried to use Sort, it complained that my CollectionBase does not inherit the IBindingList class. I've tried but I never really got far. Does anyone have any examples which will help me?
using System; using System.Collections; using System.Windows.Forms; using System.Text; using System.ComponentModel; namespace HelpDesk { class RequestCollection : CollectionBase { public void Add(Request r) { r.Parent = this; List.Add(r); } public Request this[int index] { get { return (Request)List[index]; } set { List[index] = value; } } private ImageList _Images; public ImageList Images { get { return _Images; } set { _Images = value; } } public int OpenCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Status == RequestStatus.Open) ReturnValue++; } return ReturnValue; } } public int PendingCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Status == RequestStatus.Pending) ReturnValue++; } return ReturnValue; } } public int ImmediateCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Priority == RequestPriority.Immediate) ReturnValue++; } return ReturnValue; } } public int HighCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Priority == RequestPriority.High) ReturnValue++; } return ReturnValue; }
-
Hi all, I'm working on an application, and being new to 2.0 I need some help. I have a Custom Collection which inherits CollectionBase and i'm using this as a DataGridView datasource. All is fine, apart from the Sorting does not work anymore (I used to manually add each row.) When I tried to use Sort, it complained that my CollectionBase does not inherit the IBindingList class. I've tried but I never really got far. Does anyone have any examples which will help me?
using System; using System.Collections; using System.Windows.Forms; using System.Text; using System.ComponentModel; namespace HelpDesk { class RequestCollection : CollectionBase { public void Add(Request r) { r.Parent = this; List.Add(r); } public Request this[int index] { get { return (Request)List[index]; } set { List[index] = value; } } private ImageList _Images; public ImageList Images { get { return _Images; } set { _Images = value; } } public int OpenCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Status == RequestStatus.Open) ReturnValue++; } return ReturnValue; } } public int PendingCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Status == RequestStatus.Pending) ReturnValue++; } return ReturnValue; } } public int ImmediateCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Priority == RequestPriority.Immediate) ReturnValue++; } return ReturnValue; } } public int HighCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Priority == RequestPriority.High) ReturnValue++; } return ReturnValue; }
-
Hi all, I'm working on an application, and being new to 2.0 I need some help. I have a Custom Collection which inherits CollectionBase and i'm using this as a DataGridView datasource. All is fine, apart from the Sorting does not work anymore (I used to manually add each row.) When I tried to use Sort, it complained that my CollectionBase does not inherit the IBindingList class. I've tried but I never really got far. Does anyone have any examples which will help me?
using System; using System.Collections; using System.Windows.Forms; using System.Text; using System.ComponentModel; namespace HelpDesk { class RequestCollection : CollectionBase { public void Add(Request r) { r.Parent = this; List.Add(r); } public Request this[int index] { get { return (Request)List[index]; } set { List[index] = value; } } private ImageList _Images; public ImageList Images { get { return _Images; } set { _Images = value; } } public int OpenCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Status == RequestStatus.Open) ReturnValue++; } return ReturnValue; } } public int PendingCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Status == RequestStatus.Pending) ReturnValue++; } return ReturnValue; } } public int ImmediateCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Priority == RequestPriority.Immediate) ReturnValue++; } return ReturnValue; } } public int HighCount { get { int ReturnValue = 0; foreach (Request r in List) { if (r.Priority == RequestPriority.High) ReturnValue++; } return ReturnValue; }
Hello, I think you have to call the Sort method of the InnerList property. There you have to pass an instance of a UserComparer class inheritet from IComparer. For excample, if your Request class has a Name property which you whant to use for sorting:
public class YourComparer : IComparer { int IComparer.Compare( object x, object y ) { Request request\_x= x as Request ; Request request\_y= y as Request ; if((request\_x!=null)&&(request\_y!=null)) { return( (new CaseInsensitiveComparer()).Compare( request\_x.Name, request\_y.Name ) ); } else { return 0; } } }
Hope it helps! All the best, Martin
-
Hmm, This annoys me about .Net 2.0. I want a collection dedicated to one type, and they bring out generic collections?! Probably why i've not hit that part of .Net 2.0 just yet. I've tried the following http://en.csharp-online.net/Understanding_Generics%E2%80%94Creating_a_Custom_Generic_Collection[^] but received errors. I need to be able to have methods and custom properties for my collection, if there is a way to do this, i'd be greatful if you could let me know. Thanks
-
Hmm, This annoys me about .Net 2.0. I want a collection dedicated to one type, and they bring out generic collections?! Probably why i've not hit that part of .Net 2.0 just yet. I've tried the following http://en.csharp-online.net/Understanding_Generics%E2%80%94Creating_a_Custom_Generic_Collection[^] but received errors. I need to be able to have methods and custom properties for my collection, if there is a way to do this, i'd be greatful if you could let me know. Thanks
I use List<...> for a lot of code. I find it convenient to be able to have a wrapped list. Here's an example with a simple method to demonstrate how easy it is:
using System.Collections.Generic; using System; namespace Generics.Test { public class TestGeneric { public TestGeneric() { MyList<MyTest> test = new MyList<MyTest>(); test.Add(new MyTest("Test 1")); test.Add(new MyTest("Test 2")); if (test.HasValue("Test 2")) Console.WriteLine("Test 2 is present"); } } public interface ISomeValue { string SomeValue { get; set; } } public class MyList<T> : List<T>, IEnumerable<T> where T : ISomeValue { public bool HasValue(string key) { foreach (T item in this) { if (item != null && item.SomeValue == key) return true; } return false; } #region IEnumerable<T> Members IEnumerator<T> IEnumerable<T>.GetEnumerator() { for (int i = 0; i < this.Count; i++) { yield return this[i]; } } #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new Exception("The method or operation is not implemented."); } #endregion } }
Deja View - the feeling that you've seen this post before.
-
I use List<...> for a lot of code. I find it convenient to be able to have a wrapped list. Here's an example with a simple method to demonstrate how easy it is:
using System.Collections.Generic; using System; namespace Generics.Test { public class TestGeneric { public TestGeneric() { MyList<MyTest> test = new MyList<MyTest>(); test.Add(new MyTest("Test 1")); test.Add(new MyTest("Test 2")); if (test.HasValue("Test 2")) Console.WriteLine("Test 2 is present"); } } public interface ISomeValue { string SomeValue { get; set; } } public class MyList<T> : List<T>, IEnumerable<T> where T : ISomeValue { public bool HasValue(string key) { foreach (T item in this) { if (item != null && item.SomeValue == key) return true; } return false; } #region IEnumerable<T> Members IEnumerator<T> IEnumerable<T>.GetEnumerator() { for (int i = 0; i < this.Count; i++) { yield return this[i]; } } #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new Exception("The method or operation is not implemented."); } #endregion } }
Deja View - the feeling that you've seen this post before.
Hi there, Thanks for the sample code. I've gone to use it this morning and hit another problem. I've created this:
public interface RequestCollectionInterface { ImageList Images { get; set; } int OpenCount { get; } int PendingCount { get; } int ImmediateCount { get; } int HighCount { get; } } public class RequestCollection<T> : List<T>, IEnumerable<T> where T : RequestCollectionInterface { IEnumerator<T> IEnumerable<T>.GetEnumerator() { for (int i = 0; i < this.Count; i++) { yield return this[i]; } } IEnumerator IEnumerable.GetEnumerator() { throw new Exception("The method or operation is not implemented."); } public int OpenCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Status == RequestStatus.Open) ReturnValue++; } return ReturnValue; } } public int PendingCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Status == RequestStatus.Pending) ReturnValue++; } return ReturnValue; } } public int ImmediateCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Priority = RequestPriority.Immediate) ReturnValue++; } return ReturnValue; } } public int HighCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Priority = RequestPriority.High) ReturnValue++; } return ReturnValue; } } }
And tried using it like this:private RequestCollection<Request> __GetRequests() { RequestCollection<Request> rc = new RequestCollection<Request>();
-
Hi there, Thanks for the sample code. I've gone to use it this morning and hit another problem. I've created this:
public interface RequestCollectionInterface { ImageList Images { get; set; } int OpenCount { get; } int PendingCount { get; } int ImmediateCount { get; } int HighCount { get; } } public class RequestCollection<T> : List<T>, IEnumerable<T> where T : RequestCollectionInterface { IEnumerator<T> IEnumerable<T>.GetEnumerator() { for (int i = 0; i < this.Count; i++) { yield return this[i]; } } IEnumerator IEnumerable.GetEnumerator() { throw new Exception("The method or operation is not implemented."); } public int OpenCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Status == RequestStatus.Open) ReturnValue++; } return ReturnValue; } } public int PendingCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Status == RequestStatus.Pending) ReturnValue++; } return ReturnValue; } } public int ImmediateCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Priority = RequestPriority.Immediate) ReturnValue++; } return ReturnValue; } } public int HighCount { get { int ReturnValue = 0; foreach (Request item in this) { if (item.Priority = RequestPriority.High) ReturnValue++; } return ReturnValue; } } }
And tried using it like this:private RequestCollection<Request> __GetRequests() { RequestCollection<Request> rc = new RequestCollection<Request>();
You've become slightly mixed up in what you need the interface to be. When a generic states where T : ... you are indicating that the type T will implement the interface. Also, you have used a generic list and then hardcoded the type in the iterator. To be honest, you possibly don't need to expose your class as generic because you have a specific non-generic need here. What you could do is declare a List<...> member as a private member and then use your own methods to add to it. If you definitely want to go the generic route here, this is a sample that I have just knocked up.
using System; using System.Collections.Generic; using System.Text; namespace TestIterator { class Program { static void Main(string[] args) { RequestItemCollection<Request> coll = new RequestItemCollection<Request>(); Request req = new Request(); req.Status = RequestStatus.Open; coll.Add(req); req = new Request(); req.Status = RequestStatus.Open; coll.Add(req); System.Console.WriteLine("Open count = {0}", coll.OpenCount); Console.ReadLine(); } } public class RequestItemCollection<T> : List<T>, IEnumerable<T> where T: IStatus { #region IEnumerable<T> Members IEnumerator<T> IEnumerable<T>.GetEnumerator() { for (int i = 0; i < this.Count; i++) yield return this[i]; } #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new Exception("The method or operation is not implemented."); } #endregion public int OpenCount { get { return StatusCount(RequestStatus.Open); } } public int Closed { get { return StatusCount(RequestStatus.Closed); } } private int StatusCount(RequestStatus status) { int count = 0; foreach (T item in this) { if (item.Status == status) count++; } return count; } } public enum RequestStatus { Open, Closed, Pending } public interface IStatus { RequestStatus Status { get; set; } } public class Request : IStatus { private RequestStatus _status; #region IStatus Members public RequestStatus Status { get { return _status; } set { _stat