2023-09-24 17:26:46 -04:00
using System.Collections.Generic ;
2017-11-27 13:11:20 -05:00
using System.ComponentModel ;
2023-09-29 13:58:35 -04:00
using System.Linq ;
2017-11-27 13:11:20 -05:00
using System.Reflection ;
using System.Windows.Forms ;
2018-09-22 00:35:34 -04:00
using Vanara.PInvoke ;
2017-11-27 13:11:20 -05:00
using static Vanara . PInvoke . ComCtl32 ;
2019-08-27 18:03:21 -04:00
using static Vanara . PInvoke . User32 ;
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
namespace Vanara.Extensions ;
/// <summary>Extension methods for <see cref="ListView"/>.</summary>
public static partial class ListViewExtension
2017-11-27 13:11:20 -05:00
{
2023-09-29 13:58:35 -04:00
private static PropertyInfo ? GroupIdProperty ;
2023-03-31 11:47:53 -04:00
/// <summary>Gets the items in a list view as a sequence.</summary>
/// <param name="items">The items.</param>
/// <returns></returns>
public static IEnumerable < ListViewItem > AsEnumerable ( this ListView . ListViewItemCollection items )
2017-11-27 13:11:20 -05:00
{
2023-09-29 13:58:35 -04:00
foreach ( ListViewItem item in items . Cast < ListViewItem > ( ) )
2023-03-31 11:47:53 -04:00
yield return item ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Gets the groups in a list view as a sequence.</summary>
/// <param name="items">The items.</param>
/// <returns></returns>
public static IEnumerable < ListViewGroup > AsEnumerable ( this ListViewGroupCollection items )
{
2023-09-29 13:58:35 -04:00
foreach ( ListViewGroup item in items . Cast < ListViewGroup > ( ) )
2023-03-31 11:47:53 -04:00
yield return item ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Performs an action on every item in a list view.</summary>
/// <param name="items">The items.</param>
/// <param name="action">The action.</param>
public static void ForEach ( this ListView . ListViewItemCollection items , Action < ListViewItem > action )
{
2023-09-29 13:58:35 -04:00
foreach ( ListViewItem item in items . Cast < ListViewItem > ( ) ) action ( item ) ;
2023-03-31 11:47:53 -04:00
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Gets the collapsed state of the list view group.</summary>
/// <param name="group">The list view group.</param>
/// <returns></returns>
2023-09-29 13:58:35 -04:00
/// <exception cref="ArgumentNullException"></exception>
2023-03-31 11:47:53 -04:00
public static bool GetCollapsed ( this ListViewGroup group )
{
if ( group = = null )
throw new ArgumentNullException ( ) ;
return GetState ( group , ListViewGroupState . LVGS_NORMAL | ListViewGroupState . LVGS_COLLAPSED ) ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Determines if the list view group is collapsible.</summary>
/// <param name="group">The group.</param>
/// <returns></returns>
2023-09-29 13:58:35 -04:00
/// <exception cref="ArgumentNullException"></exception>
2023-03-31 11:47:53 -04:00
public static bool GetCollapsible ( this ListViewGroup group )
{
if ( group = = null )
throw new ArgumentNullException ( ) ;
return IsWinVista ( ) & & GetState ( group , ListViewGroupState . LVGS_COLLAPSIBLE ) ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Gets the handle of the list view header.</summary>
/// <param name="listView">The list view.</param>
/// <returns></returns>
public static IntPtr GetHeaderHandle ( this ListView listView )
{
if ( listView . IsHandleCreated )
return SendMessage ( listView . Handle , ( uint ) ListViewMessage . LVM_GETHEADER , IntPtr . Zero , IntPtr . Zero ) ;
return IntPtr . Zero ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Invalidates the header.</summary>
/// <param name="listView">The list view.</param>
public static void InvalidateHeader ( this ListView listView )
{
if ( listView . IsHandleCreated & & listView . View = = View . Details )
InvalidateRect ( GetHeaderHandle ( listView ) , null , true ) ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets the collapsed state of the list view group.</summary>
/// <param name="group">The group.</param>
/// <param name="value">if set to <see langword="true"/> [value].</param>
2023-09-29 13:58:35 -04:00
/// <exception cref="ArgumentNullException"></exception>
2023-03-31 11:47:53 -04:00
public static void SetCollapsed ( this ListViewGroup group , bool value )
{
if ( group = = null )
throw new ArgumentNullException ( ) ;
SetState ( group , ListViewGroupState . LVGS_NORMAL | ListViewGroupState . LVGS_COLLAPSED , value ) ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets a value that determines if the list view group is collapsible.</summary>
/// <param name="group">The group.</param>
/// <param name="value">if set to <see langword="true"/> [value].</param>
2023-09-29 13:58:35 -04:00
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="PlatformNotSupportedException"></exception>
2023-03-31 11:47:53 -04:00
public static void SetCollapsible ( this ListViewGroup group , bool value )
{
if ( group = = null )
throw new ArgumentNullException ( ) ;
if ( ! IsWinVista ( ) )
throw new PlatformNotSupportedException ( ) ;
SetState ( group , ListViewGroupState . LVGS_COLLAPSIBLE , value ) ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets a list view header column to display as a split button or not.</summary>
/// <param name="listView">The list view.</param>
/// <param name="columnIndex">Index of the column.</param>
/// <param name="enable">if set to <see langword="true"/> show the column header as a split button.</param>
2023-09-29 13:58:35 -04:00
/// <exception cref="ArgumentOutOfRangeException">columnIndex</exception>
2023-03-31 11:47:53 -04:00
public static void SetColumnDropDown ( this ListView listView , int columnIndex , bool enable )
{
2023-09-29 13:58:35 -04:00
if ( columnIndex < 0 | | columnIndex > = 0 & & listView . Columns = = null | | columnIndex > = listView . Columns . Count )
2023-03-31 11:47:53 -04:00
throw new ArgumentOutOfRangeException ( nameof ( columnIndex ) ) ;
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
if ( listView . IsHandleCreated )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
var lvc = new LVCOLUMN ( ListViewColumMask . LVCF_FMT ) ;
var hr = listView . Handle ;
SendLVMsg ( hr , ListViewMessage . LVM_GETCOLUMN , columnIndex , lvc ) ;
lvc . Format = lvc . Format . SetFlags ( ListViewColumnFormat . LVCFMT_SPLITBUTTON , enable ) ;
SendLVMsg ( hr , ListViewMessage . LVM_SETCOLUMN , columnIndex , lvc ) ;
listView . InvalidateHeader ( ) ;
2017-11-27 13:11:20 -05:00
}
2023-03-31 11:47:53 -04:00
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Enables or disables the Explorer theme on a list view.</summary>
/// <param name="listView">The list view.</param>
/// <param name="on">if set to <see langword="true"/> [on].</param>
public static void SetExplorerTheme ( this ListView listView , bool on = true )
{
if ( IsWinVista ( ) )
2020-04-02 23:59:18 -04:00
{
2023-03-31 11:47:53 -04:00
listView . SetWindowTheme ( on ? "explorer" : null ) ;
if ( ! on ) return ;
SendMessage ( listView . Handle , ( uint ) ListViewMessage . LVM_SETEXTENDEDLISTVIEWSTYLE , ( IntPtr ) ListViewStyleEx . LVS_EX_DOUBLEBUFFER , ( IntPtr ) ListViewStyleEx . LVS_EX_DOUBLEBUFFER ) ;
2020-04-02 23:59:18 -04:00
}
2023-03-31 11:47:53 -04:00
}
2020-04-02 23:59:18 -04:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets the footer text and alignment for a list view group.</summary>
/// <param name="group">The group.</param>
/// <param name="footer">The footer text.</param>
/// <param name="footerAlignment">The footer alignment.</param>
2023-09-29 13:58:35 -04:00
public static void SetFooter ( this ListViewGroup group , string? footer = null , HorizontalAlignment footerAlignment = HorizontalAlignment . Left )
2023-03-31 11:47:53 -04:00
{
var groupId = GetGroupId ( group ) ;
2023-09-29 13:58:35 -04:00
if ( groupId > = 0 & & group . ListView ! = null )
2020-04-02 23:59:18 -04:00
{
2023-03-31 11:47:53 -04:00
using var lvgroup = new LVGROUP { Footer = footer , Alignment = MakeAlignment ( group . HeaderAlignment , footerAlignment ) } ;
SendLVMsg ( group . ListView . Handle , ListViewMessage . LVM_SETGROUPINFO , groupId , lvgroup ) ;
2020-04-02 23:59:18 -04:00
}
2023-03-31 11:47:53 -04:00
}
2020-04-02 23:59:18 -04:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets the image list to use for a list view group.</summary>
/// <param name="group">The group.</param>
/// <param name="imageList">The image list.</param>
2023-09-29 13:58:35 -04:00
/// <exception cref="InvalidOperationException"></exception>
2023-03-31 11:47:53 -04:00
public static void SetGroupImageList ( this ListViewGroup group , ImageList imageList )
{
2023-09-29 13:58:35 -04:00
if ( group . ListView is null | | ! group . ListView . IsHandleCreated )
2023-03-31 11:47:53 -04:00
throw new InvalidOperationException ( ) ;
var lparam = imageList ? . Handle ? ? IntPtr . Zero ;
SendMessage ( group . ListView . Handle , ( uint ) ListViewMessage . LVM_SETIMAGELIST , ( IntPtr ) 3 , lparam ) ;
}
2020-04-02 23:59:18 -04:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets the image index from the image list to use for a list view group.</summary>
/// <param name="group">The group.</param>
/// <param name="titleImageIndex">Index of the title image.</param>
/// <param name="descriptionTop">The description top.</param>
/// <param name="descriptionBottom">The description bottom.</param>
2023-09-29 13:58:35 -04:00
public static void SetImage ( this ListViewGroup group , int titleImageIndex , string? descriptionTop = null , string? descriptionBottom = null )
2023-03-31 11:47:53 -04:00
{
var groupId = GetGroupId ( group ) ;
2023-09-29 13:58:35 -04:00
if ( groupId > = 0 & & group . ListView ! = null )
2020-04-02 23:59:18 -04:00
{
2023-03-31 11:47:53 -04:00
using var lvgroup = new LVGROUP { TitleImageIndex = titleImageIndex } ;
if ( descriptionBottom ! = null )
lvgroup . DescriptionBottom = descriptionBottom ;
if ( descriptionTop ! = null )
lvgroup . DescriptionTop = descriptionTop ;
SendLVMsg ( group . ListView . Handle , ListViewMessage . LVM_SETGROUPINFO , groupId , lvgroup ) ;
2020-04-02 23:59:18 -04:00
}
2023-03-31 11:47:53 -04:00
}
2020-04-02 23:59:18 -04:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets the overlay image for an item in a list view.</summary>
/// <param name="lvi">The list view item.</param>
/// <param name="imageIndex">Index of the image.</param>
2023-09-29 13:58:35 -04:00
/// <exception cref="ArgumentOutOfRangeException">imageIndex</exception>
/// <exception cref="ArgumentNullException">lvi - ListViewItem must be attached to a valid ListView.</exception>
2023-03-31 11:47:53 -04:00
/// <exception cref="Win32Exception"></exception>
public static void SetOverlayImage ( this ListViewItem lvi , int imageIndex )
{
2023-09-29 13:58:35 -04:00
if ( imageIndex is < 1 or > 15 )
2023-03-31 11:47:53 -04:00
throw new ArgumentOutOfRangeException ( nameof ( imageIndex ) ) ;
if ( lvi . ListView = = null )
throw new ArgumentNullException ( nameof ( lvi ) , @"ListViewItem must be attached to a valid ListView." ) ;
var nItem = new LVITEM ( lvi . Index ) { OverlayImageIndex = ( uint ) imageIndex } ;
if ( SendLVMsg ( lvi . ListView . Handle , ListViewMessage . LVM_SETITEM , 0 , nItem ) . ToInt32 ( ) = = 0 )
throw new Win32Exception ( ) ;
}
/// <summary>Sets the sort icon displayed on a list view header column.</summary>
/// <param name="listView">The list view.</param>
/// <param name="columnIndex">Index of the column.</param>
/// <param name="order">The sort order icon to display.</param>
public static void SetSortIcon ( this ListView listView , int columnIndex , SortOrder order )
{
var columnHeader = ( HWND ) SendMessage ( listView . Handle , ( uint ) ListViewMessage . LVM_GETHEADER ) ;
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
for ( var columnNumber = 0 ; columnNumber < = listView . Columns . Count - 1 ; columnNumber + + )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
// Get current ListView column info
var lvcol = new LVCOLUMN ( ListViewColumMask . LVCF_FMT ) ;
SendLVMsg ( listView . Handle , ListViewMessage . LVM_GETCOLUMN , columnNumber , lvcol ) ;
// Get current header info
var hditem = new HDITEM ( HeaderItemMask . HDI_FORMAT | HeaderItemMask . HDI_DI_SETITEM ) ;
SendHdrMsg ( columnHeader , HeaderMessage . HDM_GETITEM , columnNumber , hditem ) ;
// Update header with column info
hditem . Format | = ( HeaderItemFormat ) ( ( uint ) lvcol . Format & 0x1001803 ) ;
if ( ( lvcol . Format & ListViewColumnFormat . LVCFMT_NO_TITLE ) = = 0 )
hditem . ShowText = true ;
// Set header image info
if ( order ! = SortOrder . None & & columnNumber = = columnIndex )
hditem . ImageDisplay = ( order = = SortOrder . Descending ) ? HeaderItemImageDisplay . DownArrow : HeaderItemImageDisplay . UpArrow ;
else
hditem . ImageDisplay = HeaderItemImageDisplay . None ;
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
// Update header
SendHdrMsg ( columnHeader , HeaderMessage . HDM_SETITEM , columnNumber , hditem ) ;
2017-11-27 13:11:20 -05:00
}
2023-03-31 11:47:53 -04:00
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Sets the task link for a list view group.</summary>
/// <param name="group">The group.</param>
/// <param name="taskLink">The task link.</param>
public static void SetTask ( this ListViewGroup group , string taskLink )
{
var groupId = GetGroupId ( group ) ;
2023-09-29 13:58:35 -04:00
if ( groupId > = 0 & & group . ListView ! = null )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
using var lvgroup = new LVGROUP { TaskLink = taskLink } ;
SendLVMsg ( group . ListView . Handle , ListViewMessage . LVM_SETGROUPINFO , groupId , lvgroup ) ;
2017-11-27 13:11:20 -05:00
}
2023-03-31 11:47:53 -04:00
}
2017-11-27 13:11:20 -05:00
2023-09-29 13:58:35 -04:00
private static void ApplyGroupingSet < T > ( this ListView listView , ListViewGroupingSet < T > set , string? nonMatchingGroupName = "Other" ) where T : class
2023-03-31 11:47:53 -04:00
{
var vm = listView . VirtualMode ;
listView . BeginUpdate ( ) ;
if ( vm )
listView . VirtualMode = false ;
listView . Groups . Clear ( ) ;
listView . Groups . AddRange ( set . Groups ) ;
var other = new List < ListViewItem > ( ) ;
2023-09-29 13:58:35 -04:00
foreach ( ListViewItem i in listView . Items . Cast < ListViewItem > ( ) )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
var found = false ;
for ( var r = 0 ; r < set . Conditions . Length ; r + + )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
if ( set . Conditions [ r ] ( i ) )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
listView . Groups [ r ] . Items . Add ( i ) ;
found = true ;
break ;
2017-11-27 13:11:20 -05:00
}
2020-04-02 23:59:18 -04:00
}
2023-03-31 11:47:53 -04:00
if ( ! found )
other . Add ( i ) ;
2017-11-27 13:11:20 -05:00
}
2023-03-31 11:47:53 -04:00
if ( other . Count > 0 & & ! string . IsNullOrEmpty ( nonMatchingGroupName ) )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
var og = listView . Groups . Add ( nonMatchingGroupName , nonMatchingGroupName ) ;
og . Items . AddRange ( other . ToArray ( ) ) ;
2017-11-27 13:11:20 -05:00
}
2023-03-31 11:47:53 -04:00
if ( vm )
listView . VirtualMode = true ;
listView . ShowGroups = true ;
listView . EndUpdate ( ) ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
private static int GetGroupId ( ListViewGroup group )
{
2023-09-29 13:58:35 -04:00
GroupIdProperty ? ? = typeof ( ListViewGroup ) . GetProperty ( "ID" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
2023-03-31 11:47:53 -04:00
return ( int? ) GroupIdProperty ? . GetValue ( group , null ) ? ? - 1 ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
private static bool GetState ( ListViewGroup group , ListViewGroupState state )
{
var groupId = GetGroupId ( group ) ;
2023-09-29 13:58:35 -04:00
if ( groupId < 0 | | group . ListView is null )
2023-03-31 11:47:53 -04:00
return false ;
return ( SendMessage ( group . ListView . Handle , ( uint ) ListViewMessage . LVM_GETGROUPSTATE , ( IntPtr ) groupId , new IntPtr ( ( int ) state ) ) . ToInt32 ( ) & ( int ) state ) ! = 0 ;
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
private static bool IsWinVista ( ) = > Environment . OSVersion . Version . Major > = 6 ;
2020-04-02 23:59:18 -04:00
2023-03-31 11:47:53 -04:00
private static ListViewGroupAlignment MakeAlignment ( HorizontalAlignment hdr , HorizontalAlignment ftr )
{
2023-09-29 13:58:35 -04:00
var h = hdr = = HorizontalAlignment . Left ? ListViewGroupAlignment . LVGA_HEADER_LEFT : ( hdr = = HorizontalAlignment . Center ? ListViewGroupAlignment . LVGA_HEADER_CENTER : ListViewGroupAlignment . LVGA_HEADER_RIGHT ) ;
2023-03-31 11:47:53 -04:00
return h | ( ftr = = HorizontalAlignment . Left ? ListViewGroupAlignment . LVGA_FOOTER_LEFT : ( ftr = = HorizontalAlignment . Center ? ListViewGroupAlignment . LVGA_FOOTER_CENTER : ListViewGroupAlignment . LVGA_FOOTER_RIGHT ) ) ;
}
2021-01-01 17:06:03 -05:00
2023-03-31 11:47:53 -04:00
private static IntPtr SendHdrMsg < TLP > ( HWND hwnd , HeaderMessage msg , int wParam , TLP lParam ) where TLP : class
{
using var lpin = new PinnedObject ( lParam ) ;
return SendMessage ( hwnd , ( uint ) msg , ( IntPtr ) wParam , lpin ) ;
}
2021-01-01 17:06:03 -05:00
2023-03-31 11:47:53 -04:00
private static IntPtr SendLVMsg < TLP > ( HWND hwnd , ListViewMessage msg , int wParam , TLP lParam ) where TLP : class
{
using var lpin = new PinnedObject ( lParam ) ;
return SendMessage ( hwnd , ( uint ) msg , ( IntPtr ) wParam , lpin ) ;
}
private static void SetState ( ListViewGroup group , ListViewGroupState state , bool value )
{
var groupId = GetGroupId ( group ) ;
2023-09-29 13:58:35 -04:00
if ( groupId > = 0 & & group . ListView ! = null )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
var lvgroup = new LVGROUP ( ListViewGroupMask . LVGF_STATE ) ;
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
lvgroup . SetState ( state , value ) ;
SendLVMsg ( group . ListView . Handle , ListViewMessage . LVM_SETGROUPINFO , groupId , lvgroup ) ;
2017-11-27 13:11:20 -05:00
}
}
2020-04-02 23:59:18 -04:00
}
2023-03-31 11:47:53 -04:00
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Takes a list of groups and matching predicates to be used by the ApplyGroupingSet extension method.</summary>
/// <typeparam name="T">Type of the item that represents and can convert to a <see cref="ListViewGroup"/>.</typeparam>
public class ListViewGroupingSet < T > where T : class
{
private readonly Converter < T , ListViewGroup > converter ;
2023-09-24 17:26:46 -04:00
private readonly List < KeyValuePair < T , Predicate < ListViewItem > > > list = new ( ) ;
2023-03-31 11:47:53 -04:00
/// <summary>Initializes a new instance of the <see cref="ListViewGroupingSet{T}"/> class.</summary>
/// <param name="converter">
/// The converter to take the <typeparamref name="T"/> and convert it to a <see cref="ListViewGroup"/>. If <typeparamref name="T"/>
/// is not <see cref="ListViewGroup"/>, an exception is thrown.
/// </param>
2023-09-29 13:58:35 -04:00
/// <exception cref="InvalidCastException">Generic type T must be convertible to a ListViewGroup.</exception>
public ListViewGroupingSet ( Converter < T , ListViewGroup > ? converter = null )
2020-04-02 23:59:18 -04:00
{
2023-03-31 11:47:53 -04:00
if ( converter ! = null )
this . converter = converter ;
else
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
if ( typeof ( T ) = = typeof ( ListViewGroup ) )
2023-09-29 13:58:35 -04:00
this . converter = a = > ( ListViewGroup ) ( object ) a ;
2020-04-02 23:59:18 -04:00
else
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
var tc = TypeDescriptor . GetConverter ( typeof ( T ) ) ;
if ( ! tc . CanConvertTo ( typeof ( ListViewGroup ) ) )
throw new InvalidCastException ( "Generic type T must be convertible to a ListViewGroup." ) ;
2023-09-29 13:58:35 -04:00
this . converter = t = > ( ListViewGroup ) ( tc . ConvertTo ( t , typeof ( ListViewGroup ) ) ? ? throw new InvalidOperationException ( "Unable to create a converter for the list view group." ) ) ;
2017-11-27 13:11:20 -05:00
}
}
2023-03-31 11:47:53 -04:00
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
internal Predicate < ListViewItem > [ ] Conditions = > list . ConvertAll ( kvp = > kvp . Value ) . ToArray ( ) ;
2023-09-29 13:58:35 -04:00
2023-03-31 11:47:53 -04:00
internal ListViewGroup [ ] Groups = > list . ConvertAll ( kvp = > converter ( kvp . Key ) ) . ToArray ( ) ;
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <summary>Adds the specified group and matching condition to the set.</summary>
/// <param name="group">The group.</param>
/// <param name="condition">The condition for <see cref="ListViewItem"/> instances to be added to the group.</param>
2023-09-29 13:58:35 -04:00
public void Add ( T group , Predicate < ListViewItem > condition ) = > list . Add ( new KeyValuePair < T , Predicate < ListViewItem > > ( group , condition ) ) ;
2017-11-27 13:11:20 -05:00
}