/* * SimpleListView.cs - Simple list view control with icons and captions. * * Copyright (C) 2004 - 2011 Andreas Scherrer * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace Level9 { /// /// Simple list view control with icons and captions. /// public class SimpleListView : Panel { // -- Constants ------------------------------------------------------ /// /// The vertical spacing between list view items in pixels. /// const int V_SPACING = 7; /// /// The spacing between component border and icons in pixels. /// const int BORDER_SPACING = 5; /// /// The vertical spacing between icons and captions in pixels. /// const int CAPTION_SPACING = 3; // -- Attributes ----------------------------------------------------- /// /// A list of list view items. /// List listViewItems = new List(); /// /// The number of the currently selected item. A value of -1 means that /// no item is selected. /// int selected = -1; // -- Events --------------------------------------------------------- /// Occurs when a list view item has been clicked. public event ListViewItemClickedEventHandler ItemClicked; // -- Constructor ---------------------------------------------------- /// /// Initializes a new instance of the SimpleListView class. /// public SimpleListView() { this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.ResizeRedraw, true); } // -- Event handling ------------------------------------------------- /// /// Handles the MouseDown event. /// protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); int item = GetItemByPoint(new Point(e.X, e.Y)); if (item >= 0) { int prevSelected = selected; selected = item; if (ItemClicked != null) { ListViewItemClickedEventArgs args = new ListViewItemClickedEventArgs(listViewItems[item]); ItemClicked(this, args); } InvalidateItem(selected); if (prevSelected >= 0) { InvalidateItem(prevSelected); } } } /// /// Handles the Paint event. /// protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; SolidBrush fgBrush = new SolidBrush(this.ForeColor); SolidBrush bgBrush = new SolidBrush(this.BackColor); SolidBrush textBrush = null; for (int i = 0; i < listViewItems.Count; i++) { SimpleListViewItem item = listViewItems[i]; Rectangle rect = GetItemRect(i); if (!rect.IntersectsWith(e.ClipRectangle)) { continue; } // // Draw background // if (i == selected) { g.FillRectangle(SystemBrushes.ActiveCaption, rect); textBrush = bgBrush; } else { g.FillRectangle(bgBrush, rect); textBrush = fgBrush; } // // Draw image // int x = this.Width / 2 - item.Image.Width / 2 - SystemInformation.Border3DSize.Width; int y = rect.Top + BORDER_SPACING; g.DrawImage(item.Image, x, y, item.Image.Width, item.Image.Height); // // Draw caption // x = this.Width / 2 - GetCaptionWidth(item.Text) / 2 - SystemInformation.Border3DSize.Width; y = rect.Top + BORDER_SPACING + item.Image.Height + CAPTION_SPACING; g.DrawString(item.Text, this.Font, textBrush, x, y); } fgBrush.Dispose(); bgBrush.Dispose(); } // -- Methods -------------------------------------------------------- /// /// Adds an item to the list view. /// /// a list view item public void AddListViewItem(SimpleListViewItem listViewItem) { if (listViewItem != null && listViewItem.Image != null) { listViewItems.Add(listViewItem); } } /// /// Sets the selected list view item. /// /// the selected list view item public void SetSelectedItem(SimpleListViewItem listViewItem) { if (listViewItem == null) { return; } for (int i = 0; i < listViewItems.Count; i++) { if (listViewItem != listViewItems[i]) { continue; } selected = i; if (ItemClicked != null) { ListViewItemClickedEventArgs args = new ListViewItemClickedEventArgs(listViewItems[i]); ItemClicked(this, args); } this.Invalidate(); break; } } /// /// Invalidates a list view item that must be redrawn. /// /// a list view item void InvalidateItem(int item) { this.Invalidate(GetItemRect(item)); } /// /// Provides the list view item that's associated with a given point /// on the component. /// /// a point on the component /// the list view item number int GetItemByPoint(Point point) { for (int i = 0; i < listViewItems.Count; i++) { Rectangle itemRect = GetItemRect(i); if (itemRect.Contains(point)) { return i; } } return -1; } /// /// Provides the rectangle that's associated with a list view item. /// /// the list view item number /// a rectangle Rectangle GetItemRect(int item) { SimpleListViewItem listViewItem = null; int yOffset = V_SPACING; for (int i = 0; i < item; i++) { listViewItem = listViewItems[i]; yOffset += V_SPACING + BORDER_SPACING * 2 + listViewItem.Image.Height + CAPTION_SPACING + this.Font.Height; } listViewItem = listViewItems[item]; int height = listViewItem.Image.Height + CAPTION_SPACING + this.Font.Height + BORDER_SPACING * 2; int width = Math.Max(GetCaptionWidth(listViewItem.Text), listViewItem.Image.Width) + BORDER_SPACING * 2 - SystemInformation.Border3DSize.Width; int xOffset = this.Width / 2 - width / 2 - 2; return new Rectangle(xOffset, yOffset, width, height); } /// /// Provides the width of a list view item's caption. /// /// the caption /// the caption width int GetCaptionWidth(string caption) { Graphics g = this.CreateGraphics(); SizeF width = g.MeasureString(caption, this.Font); g.Dispose(); return (int)Math.Ceiling(width.Width); } } /// /// Represents the method that handles a ListViewItemClicked event. /// public delegate void ListViewItemClickedEventHandler(Object sender, ListViewItemClickedEventArgs e); /// /// Provides data for the ListViewItemClicked event. /// public class ListViewItemClickedEventArgs : EventArgs { // -- Attributes ----------------------------------------------------- /// /// The list view item. /// SimpleListViewItem item = null; // -- Constructors --------------------------------------------------- /// /// Initializes a new instance of the ListViewItemClickedEventArgs /// class. /// /// the list view item public ListViewItemClickedEventArgs(SimpleListViewItem item) { this.item = item; } // -- Accessors ------------------------------------------------------ /// /// Gets or sets the list view item. /// public SimpleListViewItem Item { get { return item; } set { item = value; } } } /// /// Represents a simple list view item. /// public class SimpleListViewItem { // -- Attributes ----------------------------------------------------- /// /// The list view item's image. /// Image image = null; /// /// The text of the list view item's caption. /// string text = null; // -- Constructor ---------------------------------------------------- /// /// Initializes a new instance of the SimpleListViewItem class. /// /// the list view item's image /// the text of the list view item's caption public SimpleListViewItem(Image image, string text) { this.image = image; this.text = text; } // -- Accessors ------------------------------------------------------ /// /// Gets or sets the list view item's image. /// public Image Image { get { return this.image; } set { this.image = value; } } /// /// Gets or sets the text of the list view item's caption. /// public string Text { get { return this.text; } set { this.text = value; } } } }