⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listviewfilter.cs

📁 This control is another extension to the now standard and widely used ListView control. I have inclu
💻 CS
📖 第 1 页 / 共 4 页
字号:

      }
    }


    #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 + -