Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core.Views/3.3/ItemCollectionView.cs @ 5443

Last change on this file since 5443 was 5371, checked in by mkommend, 14 years ago

ticket #1324: Added argument null checks in (Add|Insert|Remove|Update)ListViewItem and UpdateListViewItem(Image|Text) methods.

File size: 16.7 KB
RevLine 
[2655]1#region License Information
2/* HeuristicLab
[2790]3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[2655]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
[4203]24using System.Linq;
[2655]25using System.Windows.Forms;
26using HeuristicLab.Collections;
27using HeuristicLab.MainForm;
[2713]28using HeuristicLab.MainForm.WindowsForms;
[3758]29using HeuristicLab.PluginInfrastructure;
[2655]30
31namespace HeuristicLab.Core.Views {
[2917]32  [View("ItemCollection View")]
[2727]33  [Content(typeof(ItemCollection<>), true)]
[3393]34  [Content(typeof(IItemCollection<>), false)]
[3483]35  public partial class ItemCollectionView<T> : ItemView where T : class, IItem {
[5237]36    protected Dictionary<T, List<ListViewItem>> itemListViewItemMapping;
[3407]37    protected TypeSelectorDialog typeSelectorDialog;
38
[3393]39    public new IItemCollection<T> Content {
40      get { return (IItemCollection<T>)base.Content; }
[2713]41      set { base.Content = value; }
[2655]42    }
43
44    public ListView ItemsListView {
45      get { return itemsListView; }
46    }
47
48    public ItemCollectionView() {
49      InitializeComponent();
[5237]50      itemListViewItemMapping = new Dictionary<T, List<ListViewItem>>();
[2655]51    }
52
[5237]53    protected override void Dispose(bool disposing) {
54      if (disposing) {
55        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
56        if (components != null) components.Dispose();
57      }
58      base.Dispose(disposing);
59    }
60
[2713]61    protected override void DeregisterContentEvents() {
62      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
63      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
64      Content.CollectionReset -= new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
[5237]65      foreach (T item in itemListViewItemMapping.Keys) {
66        DeregisterItemEvents(item);
[5068]67      }
[2713]68      base.DeregisterContentEvents();
[2655]69    }
[2713]70    protected override void RegisterContentEvents() {
71      base.RegisterContentEvents();
72      Content.ItemsAdded += new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
73      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
74      Content.CollectionReset += new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
[2655]75    }
[5237]76    protected virtual void DeregisterItemEvents(T item) {
77      item.ItemImageChanged -= new EventHandler(Item_ItemImageChanged);
78      item.ToStringChanged -= new EventHandler(Item_ToStringChanged);
79    }
80    protected virtual void RegisterItemEvents(T item) {
81      item.ItemImageChanged += new EventHandler(Item_ItemImageChanged);
82      item.ToStringChanged += new EventHandler(Item_ToStringChanged);
83    }
[2655]84
[2713]85    protected override void OnContentChanged() {
86      base.OnContentChanged();
[5237]87      itemsListView.Items.Clear();
88      itemListViewItemMapping.Clear();
[5057]89      RebuildImageList();
[2713]90      viewHost.Content = null;
91      if (Content != null) {
92        Caption += " (" + Content.GetType().Name + ")";
93        foreach (T item in Content)
[2655]94          AddListViewItem(CreateListViewItem(item));
[4240]95        AdjustListViewColumnSizes();
[3350]96        SortItemsListView(SortOrder.Ascending);
97      }
98    }
99
[3904]100    protected override void SetEnabledStateOfControls() {
101      base.SetEnabledStateOfControls();
[3350]102      if (Content == null) {
[3362]103        addButton.Enabled = false;
104        sortAscendingButton.Enabled = false;
105        sortDescendingButton.Enabled = false;
106        removeButton.Enabled = false;
[3350]107        itemsListView.Enabled = false;
108        detailsGroupBox.Enabled = false;
109      } else {
[3435]110        addButton.Enabled = !Content.IsReadOnly && !ReadOnly;
[3362]111        sortAscendingButton.Enabled = itemsListView.Items.Count > 1;
112        sortDescendingButton.Enabled = itemsListView.Items.Count > 1;
[3435]113        removeButton.Enabled = !Content.IsReadOnly && !ReadOnly && itemsListView.SelectedItems.Count > 0;
[3350]114        itemsListView.Enabled = true;
[4099]115        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
[2655]116      }
117    }
118
119    protected virtual T CreateItem() {
[3407]120      if (typeSelectorDialog == null) {
121        typeSelectorDialog = new TypeSelectorDialog();
122        typeSelectorDialog.Caption = "Select Item";
123        typeSelectorDialog.TypeSelector.Caption = "Available Items";
[3588]124        typeSelectorDialog.TypeSelector.Configure(typeof(T), false, true);
[2655]125      }
[3407]126
127      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
128        try {
129          return (T)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
[5302]130        }
131        catch (Exception ex) {
[3758]132          ErrorHandling.ShowErrorDialog(this, ex);
[3407]133        }
134      }
135      return null;
[2655]136    }
137    protected virtual ListViewItem CreateListViewItem(T item) {
138      ListViewItem listViewItem = new ListViewItem();
[5237]139      if (item == null) {
140        listViewItem.Text = "null";
[5287]141        itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
[5237]142        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
143      } else {
144        listViewItem.Text = item.ToString();
145        listViewItem.ToolTipText = item.ItemName + ": " + item.ItemDescription;
146        itemsListView.SmallImageList.Images.Add(item.ItemImage);
147        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
148        listViewItem.Tag = item;
149      }
[2655]150      return listViewItem;
151    }
152    protected virtual void AddListViewItem(ListViewItem listViewItem) {
[5371]153      if (listViewItem == null) throw new ArgumentNullException();
[5057]154      T item = (listViewItem.Tag as T);
[2655]155      itemsListView.Items.Add(listViewItem);
[5237]156      if (item != null) {
157        if (!itemListViewItemMapping.ContainsKey(item)) {
158          RegisterItemEvents(item);
159          itemListViewItemMapping.Add(item, new List<ListViewItem>());
160        }
161        itemListViewItemMapping[item].Add(listViewItem);
[5068]162      }
[3362]163      sortAscendingButton.Enabled = itemsListView.Items.Count > 1;
164      sortDescendingButton.Enabled = itemsListView.Items.Count > 1;
[2655]165    }
166    protected virtual void RemoveListViewItem(ListViewItem listViewItem) {
[5371]167      if (listViewItem == null) throw new ArgumentNullException();
[5057]168      T item = (listViewItem.Tag as T);
[5237]169      if (item != null) {
170        itemListViewItemMapping[item].Remove(listViewItem);
171        if (itemListViewItemMapping[item].Count == 0) {
172          itemListViewItemMapping.Remove(item);
173          DeregisterItemEvents(item);
174        }
[5057]175      }
[2655]176      listViewItem.Remove();
[3362]177      sortAscendingButton.Enabled = itemsListView.Items.Count > 1;
178      sortDescendingButton.Enabled = itemsListView.Items.Count > 1;
[2655]179    }
[3327]180    protected virtual void UpdateListViewItemImage(ListViewItem listViewItem) {
[5371]181      if (listViewItem == null) throw new ArgumentNullException();
[5237]182      T item = listViewItem.Tag as T;
[3327]183      int i = listViewItem.ImageIndex;
[5287]184      listViewItem.ImageList.Images[i] = item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage;
[3327]185      listViewItem.ImageIndex = -1;
186      listViewItem.ImageIndex = i;
187    }
188    protected virtual void UpdateListViewItemText(ListViewItem listViewItem) {
[5371]189      if (listViewItem == null) throw new ArgumentNullException();
[5237]190      T item = listViewItem.Tag as T;
191      listViewItem.Text = item == null ? "null" : item.ToString();
192      listViewItem.ToolTipText = item == null ? string.Empty : item.ItemName + ": " + item.ItemDescription;
[2655]193    }
194    protected virtual IEnumerable<ListViewItem> GetListViewItemsForItem(T item) {
[5237]195      if (item == null) {
196        List<ListViewItem> listViewItems = new List<ListViewItem>();
197        foreach (ListViewItem listViewItem in itemsListView.Items) {
198          if (listViewItem.Tag == null) listViewItems.Add(listViewItem);
199        }
200        return listViewItems;
201      } else {
[5302]202        List<ListViewItem> listViewItems = null;
203        itemListViewItemMapping.TryGetValue(item, out listViewItems);
204        return listViewItems == null ? Enumerable.Empty<ListViewItem>() : listViewItems;
[5237]205      }
[2655]206    }
207
208    #region ListView Events
209    protected virtual void itemsListView_SelectedIndexChanged(object sender, EventArgs e) {
[3456]210      removeButton.Enabled = (Content != null) && !Content.IsReadOnly && !ReadOnly && itemsListView.SelectedItems.Count > 0;
[3829]211      AdjustListViewColumnSizes();
[4096]212      if (showDetailsCheckBox.Checked) {
213        if (itemsListView.SelectedItems.Count == 1) {
214          T item = (T)itemsListView.SelectedItems[0].Tag;
215          detailsGroupBox.Enabled = true;
216          viewHost.Content = item;
217        } else {
218          viewHost.Content = null;
219          detailsGroupBox.Enabled = false;
220        }
[2655]221      }
222    }
223    protected virtual void itemsListView_KeyDown(object sender, KeyEventArgs e) {
224      if (e.KeyCode == Keys.Delete) {
[3435]225        if ((itemsListView.SelectedItems.Count > 0) && !Content.IsReadOnly && !ReadOnly) {
[2655]226          foreach (ListViewItem item in itemsListView.SelectedItems)
[2713]227            Content.Remove((T)item.Tag);
[2655]228        }
229      }
230    }
231    protected virtual void itemsListView_DoubleClick(object sender, EventArgs e) {
232      if (itemsListView.SelectedItems.Count == 1) {
[5237]233        T item = itemsListView.SelectedItems[0].Tag as T;
234        if (item != null) {
235          IContentView view = MainFormManager.MainForm.ShowContent(item);
236          if (view != null) {
237            view.ReadOnly = ReadOnly;
238            view.Locked = Locked;
239          }
[3416]240        }
[2655]241      }
242    }
243    protected virtual void itemsListView_ItemDrag(object sender, ItemDragEventArgs e) {
[3432]244      if (!Locked) {
245        ListViewItem listViewItem = (ListViewItem)e.Item;
[5237]246        T item = listViewItem.Tag as T;
247        if (item != null) {
248          DataObject data = new DataObject();
249          data.SetData("Type", item.GetType());
250          data.SetData("Value", item);
251          if (Content.IsReadOnly || ReadOnly) {
252            DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
253          } else {
254            DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
255            if ((result & DragDropEffects.Move) == DragDropEffects.Move)
256              Content.Remove(item);
257          }
[3432]258        }
[2655]259      }
260    }
261    protected virtual void itemsListView_DragEnterOver(object sender, DragEventArgs e) {
262      e.Effect = DragDropEffects.None;
263      Type type = e.Data.GetData("Type") as Type;
[3435]264      if (!Content.IsReadOnly && !ReadOnly && (type != null) && (typeof(T).IsAssignableFrom(type))) {
[3694]265        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
[2694]266        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
267        else if ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) e.Effect = DragDropEffects.Copy;
268        else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) e.Effect = DragDropEffects.Move;
[3526]269        else if ((e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) e.Effect = DragDropEffects.Link;
[2655]270      }
271    }
272    protected virtual void itemsListView_DragDrop(object sender, DragEventArgs e) {
273      if (e.Effect != DragDropEffects.None) {
274        T item = e.Data.GetData("Value") as T;
275        if ((e.Effect & DragDropEffects.Copy) == DragDropEffects.Copy) item = (T)item.Clone();
[2713]276        Content.Add(item);
[2655]277      }
278    }
279    #endregion
280
281    #region Button Events
282    protected virtual void addButton_Click(object sender, EventArgs e) {
283      T item = CreateItem();
284      if (item != null)
[2713]285        Content.Add(item);
[2655]286    }
[2676]287    protected virtual void sortAscendingButton_Click(object sender, EventArgs e) {
[2655]288      SortItemsListView(SortOrder.Ascending);
289    }
[2676]290    protected virtual void sortDescendingButton_Click(object sender, EventArgs e) {
[2655]291      SortItemsListView(SortOrder.Descending);
292    }
293    protected virtual void removeButton_Click(object sender, EventArgs e) {
294      if (itemsListView.SelectedItems.Count > 0) {
295        foreach (ListViewItem item in itemsListView.SelectedItems)
[2713]296          Content.Remove((T)item.Tag);
[2655]297        itemsListView.SelectedItems.Clear();
298      }
299    }
300    #endregion
301
[4096]302    #region CheckBox Events
303    protected virtual void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
304      if (showDetailsCheckBox.Checked) {
305        splitContainer.Panel2Collapsed = false;
306        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
307        viewHost.Content = itemsListView.SelectedItems.Count == 1 ? (T)itemsListView.SelectedItems[0].Tag : null;
308      } else {
309        splitContainer.Panel2Collapsed = true;
310        viewHost.Content = null;
311      }
312    }
313    #endregion
314
[2713]315    #region Content Events
316    protected virtual void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<T> e) {
[2655]317      if (InvokeRequired)
[2713]318        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded), sender, e);
[4240]319      else {
[2655]320        foreach (T item in e.Items)
321          AddListViewItem(CreateListViewItem(item));
[4240]322        AdjustListViewColumnSizes();
323      }
324
[2655]325    }
[2713]326    protected virtual void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<T> e) {
[2655]327      if (InvokeRequired)
[2713]328        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved), sender, e);
[2655]329      else {
330        foreach (T item in e.Items) {
[4203]331          //remove only the first matching ListViewItem, because the IItem could be contained multiple times in the ItemCollection
332          ListViewItem listviewItem = GetListViewItemsForItem(item).FirstOrDefault();
[4240]333          if (listviewItem != null) RemoveListViewItem(listviewItem);
[2655]334        }
[5057]335        RebuildImageList();
[2655]336      }
337    }
[2713]338    protected virtual void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<T> e) {
[2655]339      if (InvokeRequired)
[2713]340        Invoke(new CollectionItemsChangedEventHandler<T>(Content_CollectionReset), sender, e);
[2655]341      else {
342        foreach (T item in e.OldItems) {
[4203]343          //remove only the first matching ListViewItem, because the IItem could be contained multiple times in the ItemCollection
344          ListViewItem listviewItem = GetListViewItemsForItem(item).FirstOrDefault();
[4240]345          if (listviewItem != null) RemoveListViewItem(listviewItem);
[2655]346        }
[5057]347        RebuildImageList();
[2655]348        foreach (T item in e.Items)
349          AddListViewItem(CreateListViewItem(item));
350      }
351    }
352    #endregion
353
354    #region Item Events
[3306]355    protected virtual void Item_ItemImageChanged(object sender, EventArgs e) {
356      if (InvokeRequired)
357        Invoke(new EventHandler(Item_ItemImageChanged), sender, e);
358      else {
359        T item = (T)sender;
360        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
[3327]361          UpdateListViewItemImage(listViewItem);
[3306]362      }
363    }
[2932]364    protected virtual void Item_ToStringChanged(object sender, EventArgs e) {
[2655]365      if (InvokeRequired)
[2932]366        Invoke(new EventHandler(Item_ToStringChanged), sender, e);
[2655]367      else {
368        T item = (T)sender;
369        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
[3327]370          UpdateListViewItemText(listViewItem);
[2655]371      }
372    }
373    #endregion
374
375    #region Helpers
[2676]376    protected virtual void SortItemsListView(SortOrder sortOrder) {
[3298]377      itemsListView.Sorting = SortOrder.None;
[2655]378      itemsListView.Sorting = sortOrder;
379      itemsListView.Sorting = SortOrder.None;
380    }
[3362]381    protected virtual void AdjustListViewColumnSizes() {
382      if (itemsListView.Items.Count > 0) {
383        for (int i = 0; i < itemsListView.Columns.Count; i++)
384          itemsListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
385      }
386    }
[5239]387    protected virtual void RebuildImageList() {
[5057]388      itemsListView.SmallImageList.Images.Clear();
[5239]389      foreach (ListViewItem listViewItem in itemsListView.Items) {
390        T item = listViewItem.Tag as T;
[5287]391        itemsListView.SmallImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
[5239]392        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
[5057]393      }
394    }
[2655]395    #endregion
396  }
397}
Note: See TracBrowser for help on using the repository browser.