diff --git a/Source/ContainerListView/ContainerListView.cs b/Source/ContainerListView/ContainerListView.cs index 098b926..6fdc3ea 100644 --- a/Source/ContainerListView/ContainerListView.cs +++ b/Source/ContainerListView/ContainerListView.cs @@ -20,37 +20,21 @@ namespace Nuclex.Windows.Forms { /// public partial class ContainerListView : System.Windows.Forms.ListView { - #region struct EmbeddedControl - - /// Informationen über ein ins ListView eingebettetes Steuerelement - private struct EmbeddedControl { - /// Steuerelement das im ListView eingebetttr ist - public Control Control; - /// Spalte in der das Control eingebettet ist - public int Column; - /// Zeile in der das Control eingebettet ist - public int Row; - /// Wie das Control in der ListView-Zelle angedockt ist - public DockStyle Dock; - /// Das ListView-Element in dem sich das Control befindet - public ListViewItem Item; - } - - #endregion // struct EmbeddedControl - /// Initialisiert ein neues ListView-Steuerelement public ContainerListView() { this.embeddedControlClickedHandler = new EventHandler(embeddedControlClicked); this.embeddedControls = new ListViewEmbeddedControlCollection(); - this.embeddedControls.EmbeddedControlAdded += + this.embeddedControls.Added += new EventHandler( embeddedControlAdded ); - this.embeddedControls.EmbeddedControlRemoved += + this.embeddedControls.Removed += new EventHandler( embeddedControlRemoved ); + this.embeddedControls.Clearing += + new EventHandler(embeddedControlsClearing); InitializeComponent(); @@ -58,6 +42,22 @@ namespace Nuclex.Windows.Forms { base.AllowColumnReorder = false; } + /// Called when the list of embedded controls has been cleared + /// Collection that has been cleared of its controls + /// Not used + private void embeddedControlsClearing(object sender, EventArgs e) { + this.BeginUpdate(); + try { + foreach(ListViewEmbeddedControl embeddedControl in this.embeddedControls) { + embeddedControl.Control.Click -= this.embeddedControlClickedHandler; + this.Controls.Remove(embeddedControl.Control); + } + } + finally { + this.EndUpdate(); + } + } + /// Called when a control gets removed from the embedded controls list /// List from which the control has been removed /// Event arguments providing a reference to the removed control @@ -92,7 +92,7 @@ namespace Nuclex.Windows.Forms { foreach(ListViewEmbeddedControl embeddedControl in this.embeddedControls) { if(ReferenceEquals(embeddedControl.Control, sender)) { if((embeddedControl.Row > 0) && (embeddedControl.Row < Items.Count)) - Items[embeddedControl.Row].Selected = true; + Items[embeddedControl.Row].Selected = true; } } } @@ -100,7 +100,48 @@ namespace Nuclex.Windows.Forms { this.EndUpdate(); } } - + + /// Calculates the boundaries of a cell in the list view + /// Item in the list view from which to calculate the cell + /// Index der cell whose boundaries to calculate + /// The boundaries of the specified list view cell + /// + /// When the specified sub item index is not in the range of valid sub items + /// + protected Rectangle GetSubItemBounds(ListViewItem item, int subItem) { + + int[] order = GetColumnOrder(); + if(order == null) // No Columns + return Rectangle.Empty; + + if(subItem >= order.Length) + throw new IndexOutOfRangeException("SubItem " + subItem + " out of range"); + + // Rahmen des gesamten ListViewItems ermitteln, inklusive aller SubItems + Rectangle itemBounds = item.GetBounds(ItemBoundsPortion.Entire); + int subItemX = itemBounds.Left; + + // Horizontale Position des SubItems berechnen + // Da die Spaltenreihenfolge geändert werden kann müssen wir + // Columns[order[i]] statt Columns[i] verwenden! + ColumnHeader columnHeader; + int i; + for(i = 0; i < order.Length; ++i) { + columnHeader = this.Columns[order[i]]; + if(columnHeader.Index == subItem) + break; + + subItemX += columnHeader.Width; + } + + return new Rectangle( + subItemX, itemBounds.Top, this.Columns[order[i]].Width, itemBounds.Height + ); + + } + + /// Obtains the current column order of the list + /// An array indicating the order of the list's columns private int[] GetColumnOrder() { int[] order = new int[this.Columns.Count]; @@ -110,42 +151,6 @@ namespace Nuclex.Windows.Forms { return order; } - /// Calculates the boundaries of a cell in the list view - /// Item in the list view from which to calculate the cell - /// Index der cell whose boundaries to calculate - /// The boundaries of the specified list view cell - protected Rectangle GetSubItemBounds(ListViewItem item, int subItem) { - - int[] order = GetColumnOrder(); - if (order == null) // No Columns - return Rectangle.Empty; - - if (subItem >= order.Length) - throw new IndexOutOfRangeException("SubItem " + subItem + " out of range"); - - // Rahmen des gesamten ListViewItems ermitteln, inklusive aller SubItems - Rectangle itemBounds = item.GetBounds(ItemBoundsPortion.Entire); - int subItemX = itemBounds.Left; - - // Horizontale Position des SubItems berechnen - // Da die Spaltenreihenfolge geändert werden kann müssen wir - // Columns[order[i]] statt Columns[i] verwenden! - ColumnHeader columnHeader; - int i; - for (i = 0; i < order.Length; ++i) { - columnHeader = this.Columns[order[i]]; - if (columnHeader.Index == subItem) - break; - - subItemX += columnHeader.Width; - } - - return new Rectangle( - subItemX, itemBounds.Top, this.Columns[order[i]].Width, itemBounds.Height - ); - - } - /// Event handler for when embedded controls are clicked on private EventHandler embeddedControlClickedHandler; /// Controls being embedded in this ListView diff --git a/Source/ContainerListView/ListViewEmbeddedControl.cs b/Source/ContainerListView/ListViewEmbeddedControl.cs index 8d947da..bfa28f8 100644 --- a/Source/ContainerListView/ListViewEmbeddedControl.cs +++ b/Source/ContainerListView/ListViewEmbeddedControl.cs @@ -17,17 +17,17 @@ namespace Nuclex.Windows.Forms { this.column = column; } - /// Control that has been embedded in a ListView + /// Control that is being embedded in the ListView public Control Control { get { return this.control; } } - /// Row in the ListView the control has been embedded in + /// Row the control has been embedded in public int Row { get { return this.row; } } - /// Column in the ListView the control has been embedded in + /// Column the control has been embedded in public int Column { get { return this.column; } } @@ -38,6 +38,7 @@ namespace Nuclex.Windows.Forms { private int row; /// Column where the control is embedded private int column; + } } // namespace Nuclex.Windows.Forms diff --git a/Source/ContainerListView/ListViewEmbeddedControlCollection.cs b/Source/ContainerListView/ListViewEmbeddedControlCollection.cs index cb9e31a..9f21c87 100644 --- a/Source/ContainerListView/ListViewEmbeddedControlCollection.cs +++ b/Source/ContainerListView/ListViewEmbeddedControlCollection.cs @@ -31,12 +31,16 @@ namespace Nuclex.Windows.Forms { #endregion // class ListViewEmbeddedControlEventArgs /// Raised when a control has been added to the collection - public event EventHandler EmbeddedControlAdded; + public event EventHandler Added; /// Raised when a control is removed from the collection - public event EventHandler EmbeddedControlRemoved; + public event EventHandler Removed; + /// Raised the collection is about to be cleared + public event EventHandler Clearing; /// Removes all elements from the ListViewEmbeddedControlCollection protected override void ClearItems() { + OnClearing(); + base.ClearItems(); } @@ -49,6 +53,8 @@ namespace Nuclex.Windows.Forms { /// The zero-based index at which item should be inserted protected override void InsertItem(int index, ListViewEmbeddedControl item) { base.InsertItem(index, item); + + OnAdded(item); } /// @@ -56,7 +62,11 @@ namespace Nuclex.Windows.Forms { /// /// The zero-based index of the element to remove protected override void RemoveItem(int index) { + ListViewEmbeddedControl control = base[index]; + base.RemoveItem(index); + + OnRemoved(control); } /// Replaces the element at the specified index @@ -66,25 +76,36 @@ namespace Nuclex.Windows.Forms { /// /// The zero-based index of the element to replace protected override void SetItem(int index, ListViewEmbeddedControl item) { + ListViewEmbeddedControl control = base[index]; + base.SetItem(index, item); + + OnRemoved(control); + OnAdded(item); } - /// Fires the EmbeddedControlAdded event + /// Fires the Added event /// /// Embedded control that has been added to the collection /// - protected virtual void OnEmbeddedControlAdded(ListViewEmbeddedControl embeddedControl) { - if(EmbeddedControlAdded != null) - EmbeddedControlAdded(this, new ListViewEmbeddedControlEventArgs(embeddedControl)); + protected virtual void OnAdded(ListViewEmbeddedControl embeddedControl) { + if(Added != null) + Added(this, new ListViewEmbeddedControlEventArgs(embeddedControl)); } - /// Fires the EmbeddedControlRemoved event + /// Fires the Removed event /// /// Embedded control that has been removed from the collection /// - protected virtual void OnEmbeddedControlRemoved(ListViewEmbeddedControl embeddedControl) { - if(EmbeddedControlRemoved != null) - EmbeddedControlRemoved(this, new ListViewEmbeddedControlEventArgs(embeddedControl)); + protected virtual void OnRemoved(ListViewEmbeddedControl embeddedControl) { + if(Removed != null) + Removed(this, new ListViewEmbeddedControlEventArgs(embeddedControl)); + } + + /// Fires the Clearing event + protected virtual void OnClearing() { + if(Clearing != null) + Clearing(this, EventArgs.Empty); } }