📄 listviewfilter.cs
字号:
}
}
#endregion
#region Public properties
/// <summary>
/// Non-browsable properties
/// </summary>
[Description("The ListViewFilterHeader instance for access to " +
"the Names, Sizes, DataType, and Filter entries by column."),
Browsable(false)]
public ListViewFilterHeader Header
{
get
{
return hdr_contrl;
}
}
[Description("The LVFDataType associated with the current column " +
"that is being sorted."), Browsable(false)]
public LVFDataType SortType
{
get
{
return srt_datype;
}
}
/// <summary>
/// These are all browsable and available in the property pages.
/// NOTE: I do not know how to do two things: hide the Sorting
/// property from the page since it causes all kinds of problems,
/// and how to set a DefaultValue( Color.WhiteSmoke ) for the
/// ShadeColor property...
/// </summary>
[Description("In Details mode, the header will display filter controls."),
Category("Behavior"), DefaultValue(false)]
public bool Filtered
{
get
{
return hdr_filter;
}
set
{
if ( hdr_filter != value )
{
hdr_filter = value;
if ( hdr_contrl != null ) hdr_contrl.Filtered = hdr_filter;
this.Refresh();
}
}
}
[Description("Treat filter strings case-insensitive for comparison."),
Category("Behavior"), DefaultValue(false)]
public bool IgnoreCase
{
get
{
return flt_ignore;
}
set
{
if ( flt_ignore != value )
{
flt_ignore = value;
FilterUpdate();
}
}
}
[Description("In Details mode, the sorted column will be shaded."),
Category("Appearance"), DefaultValue(true)]
public bool Shaded
{
get
{
return col_shaded;
}
set
{
if ( col_shaded != value )
{
col_shaded = value;
this.Refresh();
}
}
}
[Description("Color of the shaded column in details mode"),
Category("Appearance")]
public Color ShadeColor
{
get
{
return col_scolor;
}
set
{
col_scolor = value;
this.Refresh();
}
}
[Description("The sorted column when in details mode."),
Category("Behavior"), DefaultValue(0)]
public int SortColumn
{
get
{
return srt_column;
}
set
{
if ( ( srt_column != value ) && ( value < this.Columns.Count ) &&
( hdr_contrl != null ) )
{
srt_column = hdr_contrl.SortColumn = value;
if ( this.View == View.Details ) this.Sort();
}
}
}
[Description("The order of the current sort. True is ascending."),
Category("Behavior"), DefaultValue(false), Browsable(false)]
public bool SortOrder
{
get
{
return srt_sorder;
}
set
{
if ( ( srt_sorder != value ) && ( hdr_contrl != null ) )
{
srt_sorder = hdr_contrl.SortOrder = value;
if ( this.View == View.Details ) this.Sort();
}
}
}
#endregion
}
/// <summary>
/// This class encapsulates the standard HeaderControl that is not
/// currently implemented in the .NET Framework. This is specific
/// for use with a ListViewFilter control in this assembly. The
/// primary reason for this is to get access to the Win32 HDM_
/// messages to get/set values that are not published by the
/// System.Windows.Forms.ColumnHeader class in .NET.
/// NOTE: This control works very well in XP since it uses the
/// HDF_SORTUP/HDF_SORTDN flags to display the up/down icon. But
/// you must have a manifest that states using CommCtrl version
/// 6.0 or greater, since that is where it is implemented...
/// </summary>
public class ListViewFilterHeader : System.Windows.Forms.NativeWindow
{
#region Private class data
readonly ListViewFilter hdr_lstvew; // owning listview control
private bool hdr_filter = false; // show filterbar in header
private int hdr_column = -1; // sort column
private bool hdr_sorder = true; // sort order
private HDITEM hdr_hditem = new HDITEM(); // instance container
#endregion
#region Windows API interfaces
[DllImport("user32.dll")] internal static extern IntPtr GetDlgItem( IntPtr hDlg, int nControlID );
[DllImport("user32.dll")] internal static extern int GetWindowLong( IntPtr hWnd, W32_GWL flag );
[DllImport("user32.dll")] internal static extern int SetWindowLong( IntPtr hWnd, W32_GWL flag, int dwNewLong );
[DllImport("user32.dll")] internal static extern int SendMessage( IntPtr hWnd, W32_HDM msg, int wParam, int lParam );
[DllImport("user32.dll")] internal static extern int SendMessage( IntPtr hWnd, W32_HDM msg, int wParam, ref HDITEM hditem );
[DllImport("user32.dll")] internal static extern int SendMessage( IntPtr hWnd, W32_HDM msg, int wParam, ref RECT rect );
#endregion
#region Constructor
/// <summary>
/// Constructor. Save the owning ListView control object and get our handle
/// assigned from it's slave controls entry 0, without it no messages are sent.
/// </summary>
/// <param name="lv">Owner</param>
public ListViewFilterHeader( ListViewFilter listview, bool filtered,
int column, bool order )
{
// save the listview instance and set initial properties
hdr_lstvew = listview;
hdr_sorder = order;
hdr_column = column;
// set the handle to this control. the first dialog item
// for a listview is this header control...
AssignHandle( GetDlgItem( hdr_lstvew.Handle, 0 ) );
// create the collection properties
DataType = new ColumnDataTypeCollection( this );
Filter = new ColumnFilterCollection( this );
Names = new ColumnNamesCollection( this );
SizeInfo = new ColumnSizeInfoCollection( this );
Alignment = new ColumnAlignmentCollection( this );
// last set the filtered property VIA SET{} METHOD
Filtered = filtered;
}
#endregion
#region Overridden System.Windows.Forms.NativeWindow methods
/// <summary>
/// When the handle changes reset the filter style.
/// </summary>
protected override void OnHandleChange()
{
base.OnHandleChange();
// reset the filter settings if there is a handle
if ( Handle != (IntPtr)0 ) ChangeFiltered();
}
#endregion
#region Private methods
/// <summary>
/// Set the window style to reflect the value of the Filtered
/// property. This is done when the Handle or property change.
/// </summary>
private void ChangeFiltered()
{
// we need to set a new style value for this control to turn
// on/off the HDS_FILTERBAR flag. First get the style itself.
const int HDS_FILTR = (int)W32_HDS.HDS_FILTERBAR;
int style = GetWindowLong( Handle, W32_GWL.GWL_STYLE );
// now that we have the flag see if it is not what is desired
if ( ( ( style & HDS_FILTR ) != 0 ) != hdr_filter )
{
// set/reset the flag for the filterbar
if ( hdr_filter ) style |= HDS_FILTR;
else style ^= HDS_FILTR;
SetWindowLong( Handle, W32_GWL.GWL_STYLE, style );
// now we have to resize this control. we do this by sending
// a set item message to column 0 to change it's size. this
// is a kludge but the invalidate and others just don't work.
hdr_hditem.mask = W32_HDI.HDI_HEIGHT;
SendMessage( Handle, W32_HDM.HDM_GETITEMW, 0, ref hdr_hditem );
hdr_hditem.cxy += ( hdr_filter ) ? 1 : -1;
SendMessage( Handle, W32_HDM.HDM_SETITEMW, 0, ref hdr_hditem );
}
// it can't hurt to set the filter timeout limit to .5 seconds
SendMessage( Handle, W32_HDM.HDM_SETFILTERCHANGETIMEOUT, 0, 500 );
// it is necessary to clear all filters which will cause a
// notification be sent to the ListView with -1 column.
SendMessage( Handle, W32_HDM.HDM_CLEARFILTER, -1, 0 );
}
/// <summary>
/// Change the column and order that is sorted. If the column
/// is the same as the current sort column, the order is
/// toggled. If it is a different column then it always sets
/// the order to ascending by default.
/// </summary>
/// <param name="Column"></param>
private void ChangeSort( int c )
{
// save the new sort column
hdr_column = c;
// setup to walk the format setting for every column
hdr_hditem.mask = W32_HDI.HDI_FORMAT;
// turn off the sorted flag for all but the current column
int i = SendMessage( Handle, W32_HDM.HDM_GETITEMCOUNT, 0, 0 );
while ( i-- > 0 )
{
// get the item information (HDITEM structure)
SendMessage( Handle, W32_HDM.HDM_GETITEMW, i, ref hdr_hditem );
// is this the column we are to flag as sorted
if ( i == hdr_column )
{
// set true when the current mode is down or none set yet
hdr_sorder = ( ( hdr_hditem.fmt & W32_HDF.HDF_SORTUP ) == 0 );
// set the new sort mode in the format
hdr_hditem.fmt &= W32_HDF.HDF_NOSORT;
hdr_hditem.fmt |= ( hdr_sorder )
? W32_HDF.HDF_SORTUP : W32_HDF.HDF_SORTDOWN;
}
// not the sort column, turn off any existing sort flag
else if ( ( hdr_hditem.fmt & W32_HDF.HDF_SORTED ) != 0 )
{
hdr_hditem.fmt &= W32_HDF.HDF_NOSORT;
}
// not the column or any sort flag, skip the format change
else continue;
// a change is needed to this column format so set it
SendMessage( Handle, W32_HDM.HDM_SETITEMW, i, ref hdr_hditem );
}
// finally invalidate the listview so that it redraws
hdr_lstvew.Invalidate( hdr_lstvew.Bounds );
}
#endregion
#region Properties
/// <summary>
/// Indexer to the alignment by column.
/// </summary>
public readonly ColumnAlignmentCollection Alignment;
/// <summary>
/// Indexer to the data types by column.
/// </summary>
public readonly ColumnDataTypeCollection DataType;
/// <summary>
/// Indexer to the column filter text.
/// </summary>
public readonly ColumnFilterCollection Filter;
/// <summary>
/// Indexer to the column name text.
/// </summary>
public readonly ColumnNamesCollection Names;
/// <summary>
/// Indexer to the column size (Width and Left as Height).
/// </summary>
public readonly ColumnSizeInfoCollection SizeInfo;
/// <summary>
/// When the Filtered property changes update the window style.
/// </summary>
public bool Filtered
{
get
{
return hdr_filter;
}
set
{
if ( hdr_filter != value )
{
hdr_filter = value;
ChangeFiltered();
}
}
}
/// <summary>
/// The column number sorted.
/// </summary>
public int SortColumn
{
get
{
return hdr_column;
}
set
{
hdr_column = value;
ChangeSort( hdr_column );
}
}
/// <summary>
/// Sort order (true is ascending).
/// </summary>
public bool SortOrder
{
get
{
return hdr_sorder;
}
set
{
if ( hdr_sorder != value )
{
hdr_sorder = value;
ChangeSort( hdr_column );
}
}
}
#endregion
#region Collection classes for indexed column access
/// <summary>
/// This is an indexer to the LVDataType values for each column.
/// The data is stored in the lParam value of the column.
/// </summary>
public class ColumnAlignmentCollection
{
readonly ListViewFilterHeader col_hdrctl = null; // owning header control
private HDITEM col_hditem = new HDITEM(); // HDITEM instance
/// <summary>
/// Constructor this must be given the header instance for access
/// to the Handle property so that messages can be sent to it.
/// </summary>
/// <param name="header">HeaderControl</param>
public ColumnAlignmentCollection( ListViewFilterHeader header )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -