📄 gradientheaders.cs
字号:
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using HardwareDistributor.Utilities;
using Microsoft.WindowsMobile.Status;
namespace HardwareDistributor.Controls
{
public partial class GradientHeaders : Control
{
#region Fields
private Brush textBrush;
private Pen borderPen;
private Color backColor;
private Color foreColor;
private ArrayList headerList;
private Graphics gxOff;
private Bitmap bitmapOff;
private ListView listView;
#endregion
#region Constructors
public GradientHeaders()
{
backColor = SystemColors.Control;
foreColor = SystemColors.ControlText;
borderPen = new Pen(Color.Black);
textBrush = new SolidBrush(foreColor);
headerList = new ArrayList();
this.Height = 22;
this.TabStop = false;
}
#endregion
#region public methods
public void Attach(ref ListView listView)
{
this.listView = listView;
headerList.Clear();
int left = 0;
// populate header collection
foreach(ColumnHeader col in listView.Columns)
{
Header header = new Header(col.Text);
header.Width = col.Width;
header.Left = left;
left += col.Width;
headerList.Add(header);
}
if (listView.HeaderStyle != ColumnHeaderStyle.None)
{
//hide the original header
listView.HeaderStyle = ColumnHeaderStyle.None;
// adjust the position of the ListView
listView.Top += this.Height;
listView.Height -= this.Height;
}
// Adjust size and position
this.Width = listView.Width;
this.Left = listView.Left;
this.Top = listView.Top - this.Height + 1;
//Create offscreen graphics
bitmapOff = new Bitmap(this.Width, this.Height);
gxOff = Graphics.FromImage(bitmapOff);
}
#endregion
#region Properties
public new Color BackColor
{
get
{
return backColor;
}
set
{
backColor = value;
}
}
public new Color ForeColor
{
get
{
return foreColor;
}
set
{
if (foreColor != value)
{
foreColor = value;
textBrush.Dispose();
textBrush = new SolidBrush(foreColor);
}
}
}
#endregion
#region base overrides
protected override void OnPaint(PaintEventArgs e)
{
// if the width is off between the two, we had a rotation event
if (listView.Width != this.Width)
{
rotation_Changed();
}
Graphics gx = gxOff;
gx.Clear(this.backColor);
GradientFill.Fill(gx, this.ClientRectangle, Color.White, Color.LightGray, GradientFill.FillDirection.TopToBottom);
Rectangle textRect = Rectangle.Empty;
int position = 0;
//draw headers
for (int i = 0; i < headerList.Count; i++)
{
Header header = (Header)headerList[i];
// Here is where we can make some autoadjustments based on the header fitting in the
// current screen size, so we could potentially add columns back in
if (header.Width != 0)
{
SizeF size = gx.MeasureString(header.Text, this.Font);
switch (header.TextAlign)
{
case HorizontalAlignment.Center:
textRect = new Rectangle((int)(header.Width - size.Width) / 2 + position, (int)(this.Height - size.Height) / 2, (int)size.Width, (int)size.Height);
break;
case HorizontalAlignment.Left:
textRect = new Rectangle(position + 5, (int)(this.Height - size.Height) / 2, (int)size.Width, (int)size.Height);
break;
case HorizontalAlignment.Right:
textRect = new Rectangle((int)(header.Width - (header.Width - size.Width)) + position, (int)(this.Height - size.Height) / 2, (int)size.Width, (int)size.Height);
break;
}
if (header.Pushed)
{
// pushed, draw the text shifted
textRect.X++;
textRect.Y++;
}
gx.DrawString(header.Text, this.Font, textBrush, textRect);
// Draw divider
gx.DrawLine(borderPen, position, 0, position, this.Height);
gx.DrawLine(new Pen(Color.White), position + 1, 0, position + 1, this.Height);
position += header.Width;
}
}
DrawBorder(gx);
// Blit to the screen
e.Graphics.DrawImage(bitmapOff, 0, 0);
//base.OnPaint (e);
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown (e);
for(int i=0;i<headerList.Count;i++)
{
Header header = (Header)headerList[i];
Rectangle headerRect = new Rectangle(header.Left, this.Top, header.Width, this.Height);
// Let's which header was pushed
if (headerRect.Contains(e.X, e.Y))
{
header.Pushed = true;
this.Invalidate();
return;
}
else
header.Pushed = false;
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp (e);
// Reset pushed flag
for(int i=0;i<headerList.Count;i++)
{
Header header = (Header)headerList[i];
if(header.Pushed)
{
header.Pushed = false;
this.Invalidate();
SortListView(i);
return;
}
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//do nothing
}
#endregion
#region helper methods
private void rotation_Changed()
{
int left = 0;
// adjust all column headers
for (int i = 0; i < listView.Columns.Count; i++)
{
ColumnHeader col = listView.Columns[i];
Header header = (Header)headerList[i];
header.Width = col.Width;
header.Left = left;
left += col.Width;
}
// Adjust size and position
this.Width = listView.Width;
this.Left = listView.Left;
this.Top = listView.Top - this.Height + 1;
//Create offscreen graphics
bitmapOff = new Bitmap(this.Width, this.Height);
gxOff = Graphics.FromImage(bitmapOff);
}
private void DrawBorder(Graphics gr)
{
Rectangle rc = this.ClientRectangle;
rc.Height--;
rc.Width--;
//Draw border
gr.DrawRectangle(borderPen, rc);
}
private void SortListView(int column)
{
Header clickedCol = (Header)headerList[column];
// Set the ascending property to sort in the opposite order.
clickedCol.ascending = !clickedCol.ascending;
// Get the number of items in the list.
int numItems = this.listView.Items.Count;
// Turn off display while data is repoplulated.
this.listView.BeginUpdate();
// Populate an ArrayList with a SortWrapper of each list item.
ArrayList SortArray = new ArrayList();
for (int i = 0; i < numItems; i++)
{
SortArray.Add(new SortWrapper(this.listView.Items[i], column));
}
// Sort the elements in the ArrayList using a new instance of the SortComparer
// class. The parameters are the starting index, the length of the range to sort,
// and the IComparer implementation to use for comparing elements. Note that
// the IComparer implementation (SortComparer) requires the sort
// direction for its constructor; true if ascending, othwise false.
SortArray.Sort(0, SortArray.Count, new SortWrapper.SortComparer(clickedCol.ascending));
// Clear the list, and repopulate with the sorted items.
this.listView.Items.Clear();
for (int i = 0; i < numItems; i++)
this.listView.Items.Add(((SortWrapper)SortArray[i]).sortItem);
// Turn display back on.
this.listView.EndUpdate();
}
#endregion
}
#region class Header
public class Header
{
private string text;
internal bool ascending;
private int width;
private HorizontalAlignment textAlign;
internal bool Pushed = false;
internal int Left = 0;
public Header(string text)
{
this.text = text;
ascending = false;
textAlign = HorizontalAlignment.Left;
}
public HorizontalAlignment TextAlign
{
get
{
return textAlign;
}
set
{
textAlign = value;
}
}
public int Width
{
get
{
return width;
}
set
{
width = value;
}
}
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
}
#endregion
#region SortWrapper class
// An instance of the SortWrapper class is created for
// each item and added to the ArrayList for sorting.
public class SortWrapper
{
internal ListViewItem sortItem;
internal int sortColumn;
// A SortWrapper requires the item and the index of the clicked column.
public SortWrapper (ListViewItem Item, int iColumn)
{
sortItem = Item;
sortColumn = iColumn;
}
// Text property for getting the text of an item.
public string Text
{
get
{
return sortItem.SubItems[sortColumn].Text;
}
}
// Implementation of the IComparer
// interface for sorting ArrayList items.
public class SortComparer : IComparer
{
bool ascending;
// Constructor requires the sort order;
// true if ascending, otherwise descending.
public SortComparer(bool asc)
{
this.ascending = asc;
}
// Implemnentation of the IComparer:Compare
// method for comparing two objects.
public int Compare(object x, object y)
{
SortWrapper xItem = (SortWrapper) x;
SortWrapper yItem = (SortWrapper) y;
string xText = xItem.sortItem.SubItems[xItem.sortColumn].Text;
string yText = yItem.sortItem.SubItems[yItem.sortColumn].Text;
return xText.CompareTo(yText) * (this.ascending ? 1 : -1);
}
}
}
#endregion
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -