c # Обновление Datagridview на основе IList - PullRequest
2 голосов
/ 24 марта 2011

У меня очень простой класс: Люди:

class People
{
   private string LastName = null;
   private string FirstName = null;
   private string Status = null;

  public string lastName
  {
     get { return LastName; }
     set { LastName = value; }
  }

  public string firstName
  {
     get { return FirstName; }
     set { FirstName = value; }
  }

  public string status
  {
     get { return Status; }
     set { Status = value; }
  }

  public People(string lastName, string firstName, string status)
  {
     LastName = lastName;
     FirstName = firstName;
     Status = status;
  }
}

И у меня есть другой класс, который реализует интерфейс IList <>, который предназначен для использования в качестве коллекции класса People, называемый PeopleList <>. PeopleList <> особенный, потому что я напрямую связываю экземпляр этого класса с DataGridView. Обычно я никогда не использовал бы IList <> в качестве источника данных для dagagview (DGV) по одной важной причине: IList не генерирует событие ListChanged, что означает, что после привязки DGV к IList <> количество строк в DGV установлен. Другими словами, если новые элементы добавляются в IList <>, DGV не будет их показывать! Единственный способ заставить это работать - установить для источника данных DGV значение null, а затем повторно привязать его к IList <> после внесения изменений.

BindingList гораздо больше подходит для этого типа потребностей, но, увы, по причинам, в которые я не могу вдаваться, обязательно, чтобы я использовал IList <> в качестве интерфейса . Чтобы обойти эту проблему, я нашел некоторый код, который предположительно интегрирует событие ListChanged в реализацию интерфейса IList <>, но у меня возникли некоторые проблемы с ним. Кажется, что даже с этим кодом у меня должен быть метод обработчика событий, верно? И в какой-то момент я должен был бы объявить этот метод в качестве обработчика для события ListChanged? Посмотрите:

class PeopleList<T> : IList<T>
   {
       private IList<T> internalList;

    public class ListChangedEventArgs : EventArgs {
      public int index;
      public T item;
      public ListChangedEventArgs(int index, T item) {
        this.index = index;
        this.item = item;
      }
    }

    public delegate void ListChangedEventHandler(object source, ListChangedEventArgs e);
    public delegate void ListClearedEventHandler(object source, EventArgs e);
    public event ListChangedEventHandler ListChanged;
    public event ListClearedEventHandler ListCleared;

    public PeopleList() {
      internalList = new List<T>();
    }

    public PeopleList(IList<T> list) {
      internalList = list;
    }



    public PeopleList(IEnumerable<T> collection) {
      internalList = new List<T>(collection);
    }

    protected virtual void OnListChanged(ListChangedEventArgs e) {
      if (ListChanged != null)
        ListChanged(this, e);
    }

    protected virtual void OnListCleared(EventArgs e) {
      if (ListCleared != null)
        ListCleared(this, e);
    }

    public int IndexOf(T item) {
      return internalList.IndexOf(item);
    }

    public void Insert(int index, T item) {
      internalList.Insert(index, item);
      OnListChanged(new ListChangedEventArgs(index, item));
    }

    public void RemoveAt(int index) {
      T item = internalList[index];
      internalList.Remove(item);
      OnListChanged(new ListChangedEventArgs(index, item));
    }

    T this[int index] {
      get { return internalList[index]; }
      set {
            internalList[index] = value;
            OnListChanged(new ListChangedEventArgs(index, value));
      }
    }

    public void Add(T item) {
      internalList.Add(item);
      OnListChanged(new ListChangedEventArgs(internalList.IndexOf(item), item));
    }

    public void Clear() {
      internalList.Clear();
      OnListCleared(new EventArgs());
    }

    public bool Contains(T item) {
      return internalList.Contains(item);
    }

    public void CopyTo(T[] array, int arrayIndex) {
      internalList.CopyTo(array, arrayIndex);
    }

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

    public bool IsReadOnly {
      get { return IsReadOnly; }
    }

    public bool Remove(T item) {
      lock(this) {
        int index = internalList.IndexOf(item);
        if (internalList.Remove(item)) {
          OnListChanged(new ListChangedEventArgs(index, item));
          return true;
        }
        else
          return false;
      }
    }

    public IEnumerator<T> GetEnumerator() {
      return internalList.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
      return ((IEnumerable) internalList).GetEnumerator();
    }


    T IList<T>.this[int index]
    {
       get
       {
          throw new NotImplementedException();
       }
       set
       {
          throw new NotImplementedException();
       }
    }

}

К вашему сведению - я занимаюсь проектированием в VS2010.

Любое руководство будет с благодарностью ... Спасибо!

1 Ответ

3 голосов
/ 01 апреля 2011

Хорошо, так что я ничего не слышал, и, кажется, нет способа сделать эту работу без серьезных побочных эффектов.В итоге я просто потрошил свой код и основал свой класс списка на System.ComponentModel.BindingList <>, который, кажется, работает нормально.Я знал, что это было возможно (как я уже упоминал в своем вопросе), но надеялся избежать утомительной работы по изменению базового класса, поскольку я не был тем, кто написал оригинальный код.Ох, колодцы.=) * * Тысяча одна

...