Initial import of Nuclex.Windows.Forms, containing a special ListView control that can contain embedded controls in its cells

git-svn-id: file:///srv/devel/repo-conversion/nuwi@1 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2007-03-30 19:52:40 +00:00
commit a82371fa93
7 changed files with 556 additions and 0 deletions

View file

@ -0,0 +1,33 @@
namespace Nuclex.Windows.Forms {
partial class ContainerListView {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
components = new System.ComponentModel.Container();
}
#endregion
}
} // namespace Nuclex.Windows.Forms

View file

@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Nuclex.Windows.Forms {
/// <summary>ListView allowing for other controls to be embedded in its cells</summary>
/// <remarks>
/// There basically were two possible design choices: Provide a specialized
/// ListViewSubItem that carries a Control instead of a string or manage the
/// embedded controls in seperation of the ListView's items. The first option
/// would require a complete rewrite of the ListViewItem class and its related
/// support classes, all of which are surprisingly large and complex. Thus,
/// the less clean but more doable latter option has been chosen.
/// </remarks>
public partial class ContainerListView : System.Windows.Forms.ListView {
#region struct EmbeddedControl
/// <summary>Informationen über ein ins ListView eingebettetes Steuerelement</summary>
private struct EmbeddedControl {
/// <summary>Steuerelement das im ListView eingebetttr ist</summary>
public Control Control;
/// <summary>Spalte in der das Control eingebettet ist</summary>
public int Column;
/// <summary>Zeile in der das Control eingebettet ist</summary>
public int Row;
/// <summary>Wie das Control in der ListView-Zelle angedockt ist</summary>
public DockStyle Dock;
/// <summary>Das ListView-Element in dem sich das Control befindet</summary>
public ListViewItem Item;
}
#endregion // struct EmbeddedControl
/// <summary>Initialisiert ein neues ListView-Steuerelement</summary>
public ContainerListView() {
this.embeddedControlClickedHandler = new EventHandler(embeddedControlClicked);
this.embeddedControls = new ListViewEmbeddedControlCollection();
this.embeddedControls.EmbeddedControlAdded +=
new EventHandler<ListViewEmbeddedControlCollection.ListViewEmbeddedControlEventArgs>(
embeddedControlAdded
);
this.embeddedControls.EmbeddedControlRemoved +=
new EventHandler<ListViewEmbeddedControlCollection.ListViewEmbeddedControlEventArgs>(
embeddedControlRemoved
);
InitializeComponent();
base.View = View.Details;
base.AllowColumnReorder = false;
}
/// <summary>Called when a control gets removed from the embedded controls list</summary>
/// <param name="sender">List from which the control has been removed</param>
/// <param name="e">Event arguments providing a reference to the removed control</param>
private void embeddedControlAdded(
object sender, ListViewEmbeddedControlCollection.ListViewEmbeddedControlEventArgs e
) {
e.EmbeddedControl.Control.Click += this.embeddedControlClickedHandler;
this.Controls.Add(e.EmbeddedControl.Control);
}
/// <summary>Called when a control gets added to the embedded controls list</summary>
/// <param name="sender">List to which the control has been added</param>
/// <param name="e">Event arguments providing a reference to the added control</param>
private void embeddedControlRemoved(
object sender, ListViewEmbeddedControlCollection.ListViewEmbeddedControlEventArgs e
) {
if(this.Controls.Contains(e.EmbeddedControl.Control)) {
e.EmbeddedControl.Control.Click -= this.embeddedControlClickedHandler;
this.Controls.Remove(e.EmbeddedControl.Control);
}
}
/// <summary>Called when an embedded control has been clicked on</summary>
/// <param name="sender">Embedded control that has been clicked</param>
/// <param name="e">Not used</param>
private void embeddedControlClicked(object sender, EventArgs e) {
this.BeginUpdate();
try {
SelectedItems.Clear();
foreach(ListViewEmbeddedControl embeddedControl in this.embeddedControls) {
if(ReferenceEquals(embeddedControl.Control, sender)) {
if((embeddedControl.Row > 0) && (embeddedControl.Row < Items.Count))
Items[embeddedControl.Row].Selected = true;
}
}
}
finally {
this.EndUpdate();
}
}
private int[] GetColumnOrder() {
int[] order = new int[this.Columns.Count];
for(int i = 0; i < this.Columns.Count; ++i)
order[this.Columns[i].DisplayIndex] = i;
return order;
}
/// <summary>Calculates the boundaries of a cell in the list view</summary>
/// <param name="item">Item in the list view from which to calculate the cell</param>
/// <param name="subItem">Index der cell whose boundaries to calculate</param>
/// <returns>The boundaries of the specified list view cell</returns>
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
);
}
/// <summary>Event handler for when embedded controls are clicked on</summary>
private EventHandler embeddedControlClickedHandler;
/// <summary>Controls being embedded in this ListView</summary>
private ListViewEmbeddedControlCollection embeddedControls;
}
} // namespace Nuclex.Windows.Forms

View file

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Nuclex.Windows.Forms {
/// <summary>Stores informations about an embedded control</summary>
public class ListViewEmbeddedControl {
/// <summary>Initializes a new embedded control holder</summary>
/// <param name="control">Control being embedded in a list view</param>
/// <param name="row">List row at which the control will be embedded</param>
/// <param name="column">List column at which the control will be embedded</param>
public ListViewEmbeddedControl(Control control, int row, int column) {
this.control = control;
this.row = row;
this.column = column;
}
/// <summary>Control that has been embedded in a ListView</summary>
public Control Control {
get { return this.control; }
}
/// <summary>Row in the ListView the control has been embedded in</summary>
public int Row {
get { return this.row; }
}
/// <summary>Column in the ListView the control has been embedded in</summary>
public int Column {
get { return this.column; }
}
/// <summary>Embedded control</summary>
private Control control;
/// <summary>Row where the control is embedded</summary>
private int row;
/// <summary>Column where the control is embedded</summary>
private int column;
}
} // namespace Nuclex.Windows.Forms

View file

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Nuclex.Windows.Forms {
/// <summary>Collection of controls embedded in a ListView</summary>
public class ListViewEmbeddedControlCollection : Collection<ListViewEmbeddedControl> {
#region class ListViewEmbeddedControlEventArgs
/// <summary>Arguments class for events that need to pass a control</summary>
public class ListViewEmbeddedControlEventArgs : EventArgs {
/// <summary>Initializes a new event arguments supplier</summary>
/// <param name="embeddedControl">Control to be supplied to the event handler</param>
public ListViewEmbeddedControlEventArgs(ListViewEmbeddedControl embeddedControl) {
this.embeddedControl = embeddedControl;
}
/// <summary>Obtains the control the event arguments are carrying</summary>
public ListViewEmbeddedControl EmbeddedControl {
get { return this.embeddedControl; }
}
/// <summary>Control that's passed to the event handler</summary>
private ListViewEmbeddedControl embeddedControl;
}
#endregion // class ListViewEmbeddedControlEventArgs
/// <summary>Raised when a control has been added to the collection</summary>
public event EventHandler<ListViewEmbeddedControlEventArgs> EmbeddedControlAdded;
/// <summary>Raised when a control is removed from the collection</summary>
public event EventHandler<ListViewEmbeddedControlEventArgs> EmbeddedControlRemoved;
/// <summary>Removes all elements from the ListViewEmbeddedControlCollection</summary>
protected override void ClearItems() {
base.ClearItems();
}
/// <summary>
/// Inserts an element into the ListViewEmbeddedControlCollection at the specified index
/// </summary>
/// <param name="index">
/// The object to insert. The value can be null for reference types
/// </param>
/// <param name="item">The zero-based index at which item should be inserted</param>
protected override void InsertItem(int index, ListViewEmbeddedControl item) {
base.InsertItem(index, item);
}
/// <summary>
/// Removes the element at the specified index of the ListViewEmbeddedControlCollection
/// </summary>
/// <param name="index">The zero-based index of the element to remove</param>
protected override void RemoveItem(int index) {
base.RemoveItem(index);
}
/// <summary>Replaces the element at the specified index</summary>
/// <param name="index">
/// The new value for the element at the specified index. The value can be null
/// for reference types
/// </param>
/// <param name="item">The zero-based index of the element to replace</param>
protected override void SetItem(int index, ListViewEmbeddedControl item) {
base.SetItem(index, item);
}
/// <summary>Fires the EmbeddedControlAdded event</summary>
/// <param name="embeddedControl">
/// Embedded control that has been added to the collection
/// </param>
protected virtual void OnEmbeddedControlAdded(ListViewEmbeddedControl embeddedControl) {
if(EmbeddedControlAdded != null)
EmbeddedControlAdded(this, new ListViewEmbeddedControlEventArgs(embeddedControl));
}
/// <summary>Fires the EmbeddedControlRemoved event</summary>
/// <param name="embeddedControl">
/// Embedded control that has been removed from the collection
/// </param>
protected virtual void OnEmbeddedControlRemoved(ListViewEmbeddedControl embeddedControl) {
if(EmbeddedControlRemoved != null)
EmbeddedControlRemoved(this, new ListViewEmbeddedControlEventArgs(embeddedControl));
}
}
} // namespace Nuclex.Windows.Forms

View file

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Nuclex.Windows.Forms {
/// <summary>Collection of controls embedded in another control</summary>
public class EmbeddedControlCollection : Control.ControlCollection {
#region class ControlEventArgs
/// <summary>Arguments class for events that need to pass a control</summary>
public class ControlEventArgs : EventArgs {
/// <summary>Initializes a new event arguments provider</summary>
/// <param name="control">Control to be supplied to the event handler</param>
public ControlEventArgs(Control control) {
this.control = control;
}
/// <summary>Obtains the control the event arguments are carrying</summary>
public Control Control { get { return this.control; } }
/// <summary>Control that's passed to the event handler</summary>
private Control control;
}
#endregion // class ControlEventArgs
/// <summary>Raised when a control has been added to the collection</summary>
public event EventHandler<ControlEventArgs> ControlAdded;
/// <summary>Raised when a control is removed from the collection</summary>
public event EventHandler<ControlEventArgs> ControlRemoved;
/// <summary>Initializes a new instance of the EmbeddedControlCollection class</summary>
/// <param name="owner">
/// A System.Windows.Forms.Control representing the control
/// that owns the control collection
/// </param>
EmbeddedControlCollection(Control owner) : base(owner) { }
/// <summary>Adds the specified control to the control collection</summary>
/// <param name="value">
/// The System.Windows.Forms.Control to add to the control collection
/// </param>
public override void Add(Control value) {
base.Add(value);
OnControlAdded(value);
}
/// <summary>Removes the specified control from the control collection</summary>
/// <param name="value">
/// The System.Windows.Forms.Control to remove from the EmbeddedControlCollection
/// </param>
public override void Remove(Control value) {
base.Remove(value);
OnControlRemoved(value);
}
/*
/// <summary>Adds an array of control objects to the collection</summary>
/// <param name="controls">
/// An array of System.Windows.Forms.Control objects to add to the collection
/// </param>
public override void AddRange(Control[] controls) {
base.AddRange(controls);
}
/// <summary>Removes all controls from the collection</summary>
public override void Clear() {
base.Clear();
}
/// <summary>Removes the child control with the specified key</summary>
/// <param name="key">The name of the child control to remove</param>
public override void RemoveByKey(string key) {
base.RemoveByKey(key);
}
*/
/// <summary>
/// Called when a control has been added to the collection,
/// fires the ControlAdded event
/// </summary>
/// <param name="control">Control that has been added to the collection</param>
protected virtual void OnControlAdded(Control control) {
if(ControlAdded != null)
ControlAdded(this, new ControlEventArgs(control));
}
/// <summary>
/// Called when a control has been removed to the collection,
/// fires the ControlRemoved event
/// </summary>
/// <param name="control">Control that has been removed from the collection</param>
protected virtual void OnControlRemoved(Control control) {
if(ControlRemoved != null)
ControlRemoved(this, new ControlEventArgs(control));
}
}
} // namespace Nuclex.Windows.Forms