зеркало из https://github.com/dotnet/winforms.git
Implement TitleImageIndex/Key to ListViewGroup (#3490)
This commit is contained in:
Родитель
3d6c0bb497
Коммит
d4fca96a43
|
@ -0,0 +1,6 @@
|
|||
System.Windows.Forms.ListViewGroup.TitleImageIndex.get -> int
|
||||
System.Windows.Forms.ListViewGroup.TitleImageIndex.set -> void
|
||||
System.Windows.Forms.ListViewGroup.TitleImageKey.get -> string!
|
||||
System.Windows.Forms.ListViewGroup.TitleImageKey.set -> void
|
||||
~System.Windows.Forms.ListView.GroupImageList.get -> System.Windows.Forms.ImageList
|
||||
~System.Windows.Forms.ListView.GroupImageList.set -> void
|
|
@ -6710,4 +6710,7 @@ Stack trace where the illegal operation occurred was:
|
|||
<data name="InputLanguageCultureNotFound" xml:space="preserve">
|
||||
<value>Could not find an InputLanguage for culture '{0}'.</value>
|
||||
</data>
|
||||
<data name="ListViewGroupImageListDescr" xml:space="preserve">
|
||||
<value>The ImageList control used by the ListView for ListViewGroup images in all views.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Trasování zásobníku, kde došlo k neplatné operaci:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Název této skupiny</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Der Name dieser Gruppe.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Nombre de este grupo.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Cette opération non conforme s'est produite sur la trace de la pile :
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Nom de ce groupe.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Traccia dello stack da cui si è verificata l'operazione non valida:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Il nome del gruppo.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Stack trace where the illegal operation occurred was:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">このグループの名前です。</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Stack trace where the illegal operation occurred was:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">이 그룹의 이름입니다.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Nazwa tej grupy.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Rastreamento de pilha em que a operação ilegal ocorreu:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">O nome deste grupo.</target>
|
||||
|
|
|
@ -6377,6 +6377,11 @@ Stack trace where the illegal operation occurred was:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Имя данной группы.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Geçersiz işlemin gerçekleştiği yığın izi:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">Bu grubun adı.</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Stack trace where the illegal operation occurred was:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">此组的名称。</target>
|
||||
|
|
|
@ -6376,6 +6376,11 @@ Stack trace where the illegal operation occurred was:
|
|||
<target state="translated">ListViewGroup</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupImageListDescr">
|
||||
<source>The ImageList control used by the ListView for ListViewGroup images in all views.</source>
|
||||
<target state="new">The ImageList control used by the ListView for ListViewGroup images in all views.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ListViewGroupNameDescr">
|
||||
<source>The name of this group.</source>
|
||||
<target state="translated">此群組的名稱。</target>
|
||||
|
|
|
@ -110,9 +110,10 @@ namespace System.Windows.Forms
|
|||
private IntPtr odCacheFontHandle = IntPtr.Zero;
|
||||
private FontHandleWrapper odCacheFontHandleWrapper = null;
|
||||
|
||||
private ImageList imageListLarge;
|
||||
private ImageList imageListSmall;
|
||||
private ImageList imageListState;
|
||||
private ImageList _imageListLarge;
|
||||
private ImageList _imageListSmall;
|
||||
private ImageList _imageListState;
|
||||
private ImageList _imageListGroup;
|
||||
|
||||
private MouseButtons downButton;
|
||||
private int itemCount;
|
||||
|
@ -574,11 +575,11 @@ namespace System.Windows.Forms
|
|||
// Setting the LVS_CHECKBOXES window style also causes the ListView to display the default checkbox
|
||||
// images rather than the user specified StateImageList. We send a LVM_SETIMAGELIST to restore the
|
||||
// user's images.
|
||||
if (IsHandleCreated && imageListState != null)
|
||||
if (IsHandleCreated && _imageListState != null)
|
||||
{
|
||||
if (CheckBoxes)
|
||||
{ // we want custom checkboxes
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, imageListState.Handle);
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, _imageListState.Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -925,6 +926,51 @@ namespace System.Windows.Forms
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The currently set GroupIcon image list.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// An <see cref="ImageList"/> that contains the icons to use for <see cref="ListViewGroup"/>.
|
||||
/// The default is <see langword="null"/>.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The <see cref="GroupImageList"/> property allows you to specify an <see cref="ImageList"/> object that
|
||||
/// contains icons to use when displaying groups. The <see cref="ListView"/> control can accept any graphics
|
||||
/// format that the <see cref="ImageList"/> control supports when displaying icons. The <see cref="ListView"/>
|
||||
/// control is not limited to .ico files. Once an <see cref="ImageList"/> is assigned to the <see cref="GroupImageList"/>
|
||||
/// property, you can set the <see cref="ListViewGroup.TitleImageIndex"/> property of each <see cref="ListViewGroup"/>
|
||||
/// in the <see cref="ListView"/> control to the index position of the appropriate image in the <see cref="ImageList"/>.
|
||||
/// The size of the icons for the <see cref="GroupImageList"/> is specified by the <see cref="ImageList.ImageSize"/> property.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
[SRCategory(nameof(SR.CatBehavior))]
|
||||
[DefaultValue(null)]
|
||||
[SRDescription(nameof(SR.ListViewGroupImageListDescr))]
|
||||
public ImageList GroupImageList
|
||||
{
|
||||
get => _imageListGroup;
|
||||
set
|
||||
{
|
||||
if (_imageListGroup == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DetachGroupImageListHandlers();
|
||||
_imageListGroup = value;
|
||||
AttachGroupImageListHandlers();
|
||||
|
||||
if (!IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.GROUPHEADER,
|
||||
value is null ? IntPtr.Zero : value.Handle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The collection of groups belonging to this ListView
|
||||
/// </summary>
|
||||
|
@ -1172,16 +1218,16 @@ namespace System.Windows.Forms
|
|||
[SRDescription(nameof(SR.ListViewLargeImageListDescr))]
|
||||
public ImageList LargeImageList
|
||||
{
|
||||
get => imageListLarge;
|
||||
get => _imageListLarge;
|
||||
set
|
||||
{
|
||||
if (value == imageListLarge)
|
||||
if (value == _imageListLarge)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DetachLargeImageListHandlers();
|
||||
imageListLarge = value;
|
||||
_imageListLarge = value;
|
||||
AttachLargeImageListHandlers();
|
||||
|
||||
if (!IsHandleCreated)
|
||||
|
@ -1411,16 +1457,16 @@ namespace System.Windows.Forms
|
|||
[SRDescription(nameof(SR.ListViewSmallImageListDescr))]
|
||||
public ImageList SmallImageList
|
||||
{
|
||||
get => imageListSmall;
|
||||
get => _imageListSmall;
|
||||
set
|
||||
{
|
||||
if (imageListSmall == value)
|
||||
if (_imageListSmall == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DetachSmallImageListListHandlers();
|
||||
imageListSmall = value;
|
||||
_imageListSmall = value;
|
||||
AttachSmallImageListListHandlers();
|
||||
|
||||
if (!IsHandleCreated)
|
||||
|
@ -1520,10 +1566,10 @@ namespace System.Windows.Forms
|
|||
[SRDescription(nameof(SR.ListViewStateImageListDescr))]
|
||||
public ImageList StateImageList
|
||||
{
|
||||
get => imageListState;
|
||||
get => _imageListState;
|
||||
set
|
||||
{
|
||||
if (imageListState == value)
|
||||
if (_imageListState == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1531,7 +1577,7 @@ namespace System.Windows.Forms
|
|||
if (UseCompatibleStateImageBehavior)
|
||||
{
|
||||
DetachStateImageListHandlers();
|
||||
imageListState = value;
|
||||
_imageListState = value;
|
||||
AttachStateImageListHandlers();
|
||||
|
||||
if (IsHandleCreated)
|
||||
|
@ -1543,7 +1589,7 @@ namespace System.Windows.Forms
|
|||
{
|
||||
DetachStateImageListHandlers();
|
||||
|
||||
if (IsHandleCreated && imageListState != null && CheckBoxes)
|
||||
if (IsHandleCreated && _imageListState != null && CheckBoxes)
|
||||
{
|
||||
// If CheckBoxes are set to true, then we will have to recreate the handle.
|
||||
// For some reason, if CheckBoxes are set to true and the list view has a state imageList, then the native listView destroys
|
||||
|
@ -1554,7 +1600,7 @@ namespace System.Windows.Forms
|
|||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, IntPtr.Zero);
|
||||
}
|
||||
|
||||
imageListState = value;
|
||||
_imageListState = value;
|
||||
AttachStateImageListHandlers();
|
||||
|
||||
if (!IsHandleCreated)
|
||||
|
@ -1569,7 +1615,8 @@ namespace System.Windows.Forms
|
|||
}
|
||||
else
|
||||
{
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, (imageListState is null || imageListState.Images.Count == 0) ? IntPtr.Zero : imageListState.Handle);
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE,
|
||||
(_imageListState is null || _imageListState.Images.Count == 0) ? IntPtr.Zero : _imageListState.Handle);
|
||||
}
|
||||
|
||||
// Comctl should handle auto-arrange for us, but doesn't
|
||||
|
@ -2204,41 +2251,54 @@ namespace System.Windows.Forms
|
|||
/// </summary>
|
||||
public void ArrangeIcons() => ArrangeIcons((ListViewAlignment)LVA.DEFAULT);
|
||||
|
||||
private void AttachGroupImageListHandlers()
|
||||
{
|
||||
if (_imageListGroup is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: any handlers added here should be removed in DetachGroupImageListHandlers
|
||||
_imageListGroup.RecreateHandle += new EventHandler(GroupImageListRecreateHandle);
|
||||
_imageListGroup.Disposed += new EventHandler(DetachImageList);
|
||||
_imageListGroup.ChangeHandle += new EventHandler(GroupImageListChangedHandle);
|
||||
}
|
||||
|
||||
private void AttachLargeImageListHandlers()
|
||||
{
|
||||
if (imageListLarge is null)
|
||||
if (_imageListLarge is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: any handlers added here should be removed in DetachLargeImageListHandlers
|
||||
imageListLarge.RecreateHandle += new EventHandler(LargeImageListRecreateHandle);
|
||||
imageListLarge.Disposed += new EventHandler(DetachImageList);
|
||||
imageListLarge.ChangeHandle += new EventHandler(LargeImageListChangedHandle);
|
||||
_imageListLarge.RecreateHandle += new EventHandler(LargeImageListRecreateHandle);
|
||||
_imageListLarge.Disposed += new EventHandler(DetachImageList);
|
||||
_imageListLarge.ChangeHandle += new EventHandler(LargeImageListChangedHandle);
|
||||
}
|
||||
|
||||
private void AttachSmallImageListListHandlers()
|
||||
{
|
||||
if (imageListSmall is null)
|
||||
if (_imageListSmall is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: any handlers added here should be removed in DetachSmallImageListListHandlers
|
||||
imageListSmall.RecreateHandle += new EventHandler(SmallImageListRecreateHandle);
|
||||
imageListSmall.Disposed += new EventHandler(DetachImageList);
|
||||
_imageListSmall.RecreateHandle += new EventHandler(SmallImageListRecreateHandle);
|
||||
_imageListSmall.Disposed += new EventHandler(DetachImageList);
|
||||
}
|
||||
|
||||
private void AttachStateImageListHandlers()
|
||||
{
|
||||
if (imageListState is null)
|
||||
if (_imageListState is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: any handlers added here should be removed in DetachStateImageListHandlers
|
||||
imageListState.RecreateHandle += new EventHandler(StateImageListRecreateHandle);
|
||||
imageListState.Disposed += new EventHandler(DetachImageList);
|
||||
_imageListState.RecreateHandle += new EventHandler(StateImageListRecreateHandle);
|
||||
_imageListState.Disposed += new EventHandler(DetachImageList);
|
||||
}
|
||||
|
||||
public void AutoResizeColumns(ColumnHeaderAutoResizeStyle headerAutoResize)
|
||||
|
@ -2888,25 +2948,30 @@ namespace System.Windows.Forms
|
|||
try
|
||||
{
|
||||
#if DEBUG
|
||||
if (sender != imageListSmall && sender != imageListState && sender != imageListLarge)
|
||||
if (sender != _imageListSmall && sender != _imageListState && sender != _imageListLarge && sender != _imageListGroup)
|
||||
{
|
||||
Debug.Fail("ListView sunk dispose event from unknown component");
|
||||
}
|
||||
#endif // DEBUG
|
||||
if (sender == imageListSmall)
|
||||
if (sender == _imageListSmall)
|
||||
{
|
||||
SmallImageList = null;
|
||||
}
|
||||
|
||||
if (sender == imageListLarge)
|
||||
if (sender == _imageListLarge)
|
||||
{
|
||||
LargeImageList = null;
|
||||
}
|
||||
|
||||
if (sender == imageListState)
|
||||
if (sender == _imageListState)
|
||||
{
|
||||
StateImageList = null;
|
||||
}
|
||||
|
||||
if (sender == _imageListGroup)
|
||||
{
|
||||
GroupImageList = null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -2916,38 +2981,50 @@ namespace System.Windows.Forms
|
|||
UpdateListViewItemsLocations();
|
||||
}
|
||||
|
||||
private void DetachLargeImageListHandlers()
|
||||
private void DetachGroupImageListHandlers()
|
||||
{
|
||||
if (imageListLarge is null)
|
||||
if (_imageListGroup is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
imageListLarge.RecreateHandle -= new EventHandler(LargeImageListRecreateHandle);
|
||||
imageListLarge.Disposed -= new EventHandler(DetachImageList);
|
||||
imageListLarge.ChangeHandle -= new EventHandler(LargeImageListChangedHandle);
|
||||
_imageListGroup.RecreateHandle -= new EventHandler(GroupImageListRecreateHandle);
|
||||
_imageListGroup.Disposed -= new EventHandler(DetachImageList);
|
||||
_imageListGroup.ChangeHandle -= new EventHandler(GroupImageListChangedHandle);
|
||||
}
|
||||
|
||||
private void DetachLargeImageListHandlers()
|
||||
{
|
||||
if (_imageListLarge is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_imageListLarge.RecreateHandle -= new EventHandler(LargeImageListRecreateHandle);
|
||||
_imageListLarge.Disposed -= new EventHandler(DetachImageList);
|
||||
_imageListLarge.ChangeHandle -= new EventHandler(LargeImageListChangedHandle);
|
||||
}
|
||||
|
||||
private void DetachSmallImageListListHandlers()
|
||||
{
|
||||
if (imageListSmall is null)
|
||||
if (_imageListSmall is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
imageListSmall.RecreateHandle -= new EventHandler(SmallImageListRecreateHandle);
|
||||
imageListSmall.Disposed -= new EventHandler(DetachImageList);
|
||||
_imageListSmall.RecreateHandle -= new EventHandler(SmallImageListRecreateHandle);
|
||||
_imageListSmall.Disposed -= new EventHandler(DetachImageList);
|
||||
}
|
||||
|
||||
private void DetachStateImageListHandlers()
|
||||
{
|
||||
if (imageListState is null)
|
||||
if (_imageListState is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
imageListState.RecreateHandle -= new EventHandler(StateImageListRecreateHandle);
|
||||
imageListState.Disposed -= new EventHandler(DetachImageList);
|
||||
_imageListState.RecreateHandle -= new EventHandler(StateImageListRecreateHandle);
|
||||
_imageListState.Disposed -= new EventHandler(DetachImageList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2961,11 +3038,13 @@ namespace System.Windows.Forms
|
|||
{
|
||||
// Remove any event sinks we have hooked up to imageLists
|
||||
DetachSmallImageListListHandlers();
|
||||
imageListSmall = null;
|
||||
_imageListSmall = null;
|
||||
DetachLargeImageListHandlers();
|
||||
imageListLarge = null;
|
||||
_imageListLarge = null;
|
||||
DetachStateImageListHandlers();
|
||||
imageListState = null;
|
||||
_imageListState = null;
|
||||
DetachGroupImageListHandlers();
|
||||
_imageListGroup = null;
|
||||
|
||||
// Remove any ColumnHeaders contained in this control
|
||||
if (columnHeaders != null)
|
||||
|
@ -3582,6 +3661,32 @@ namespace System.Windows.Forms
|
|||
return result;
|
||||
}
|
||||
|
||||
private void GroupImageListChangedHandle(object sender, EventArgs e)
|
||||
{
|
||||
if (VirtualMode || sender is null || sender != _imageListGroup || !IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ListViewGroup group in Groups)
|
||||
{
|
||||
group.TitleImageIndex = group.ImageIndexer.ActualIndex < _imageListGroup.Images.Count
|
||||
? group.ImageIndexer.ActualIndex
|
||||
: _imageListGroup.Images.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void GroupImageListRecreateHandle(object sender, EventArgs e)
|
||||
{
|
||||
if (!IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IntPtr handle = (GroupImageList is null) ? IntPtr.Zero : GroupImageList.Handle;
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.GROUPHEADER, handle);
|
||||
}
|
||||
|
||||
public ListViewHitTestInfo HitTest(Point point)
|
||||
{
|
||||
return HitTest(point.X, point.Y);
|
||||
|
@ -4144,32 +4249,30 @@ namespace System.Windows.Forms
|
|||
|
||||
private void LargeImageListRecreateHandle(object sender, EventArgs e)
|
||||
{
|
||||
if (IsHandleCreated)
|
||||
if (!IsHandleCreated)
|
||||
{
|
||||
IntPtr handle = (LargeImageList == null) ? IntPtr.Zero : LargeImageList.Handle;
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.NORMAL, handle);
|
||||
|
||||
ForceCheckBoxUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
IntPtr handle = (LargeImageList is null) ? IntPtr.Zero : LargeImageList.Handle;
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.NORMAL, handle);
|
||||
|
||||
ForceCheckBoxUpdate();
|
||||
}
|
||||
|
||||
private void LargeImageListChangedHandle(object sender, EventArgs e)
|
||||
{
|
||||
if (VirtualMode || sender is null || sender != imageListLarge || !IsHandleCreated)
|
||||
if (VirtualMode || sender is null || sender != _imageListLarge || !IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ListViewItem item in Items)
|
||||
{
|
||||
if (item.ImageIndexer.ActualIndex != ImageList.Indexer.DefaultIndex && item.ImageIndexer.ActualIndex >= imageListLarge.Images.Count)
|
||||
{
|
||||
SetItemImage(item.Index, imageListLarge.Images.Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetItemImage(item.Index, item.ImageIndexer.ActualIndex);
|
||||
}
|
||||
int imageIndex = item.ImageIndexer.ActualIndex < _imageListLarge.Images.Count
|
||||
? item.ImageIndexer.ActualIndex
|
||||
: _imageListLarge.Images.Count - 1;
|
||||
SetItemImage(item.Index, imageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4728,19 +4831,24 @@ namespace System.Windows.Forms
|
|||
User32.SendMessageW(this, (User32.WM)LVM.SETTEXTCOLOR, IntPtr.Zero, PARAM.FromColor(c));
|
||||
}
|
||||
|
||||
if (null != imageListLarge)
|
||||
if (_imageListLarge != null)
|
||||
{
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.NORMAL, imageListLarge.Handle);
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.NORMAL, _imageListLarge.Handle);
|
||||
}
|
||||
|
||||
if (null != imageListSmall)
|
||||
if (_imageListSmall != null)
|
||||
{
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.SMALL, imageListSmall.Handle);
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.SMALL, _imageListSmall.Handle);
|
||||
}
|
||||
|
||||
if (null != imageListState)
|
||||
if (_imageListState != null)
|
||||
{
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, imageListState.Handle);
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, _imageListState.Handle);
|
||||
}
|
||||
|
||||
if (_imageListGroup != null)
|
||||
{
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.GROUPHEADER, _imageListGroup.Handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5124,11 +5232,11 @@ namespace System.Windows.Forms
|
|||
User32.DestroyWindow(oldHandle);
|
||||
}
|
||||
|
||||
internal void SetItemImage(int index, int image)
|
||||
internal void SetItemImage(int itemIndex, int imageIndex)
|
||||
{
|
||||
if (index < 0 || (VirtualMode && index >= VirtualListSize) || (!VirtualMode && index >= itemCount))
|
||||
if (itemIndex < 0 || (VirtualMode && itemIndex >= VirtualListSize) || (!VirtualMode && itemIndex >= itemCount))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index));
|
||||
throw new ArgumentOutOfRangeException(nameof(itemIndex), itemIndex, string.Format(SR.InvalidArgument, nameof(itemIndex), itemIndex));
|
||||
}
|
||||
|
||||
if (!IsHandleCreated)
|
||||
|
@ -5139,8 +5247,8 @@ namespace System.Windows.Forms
|
|||
var lvItem = new LVITEMW
|
||||
{
|
||||
mask = LVIF.IMAGE,
|
||||
iItem = index,
|
||||
iImage = image
|
||||
iItem = itemIndex,
|
||||
iImage = imageIndex
|
||||
};
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETITEMW, IntPtr.Zero, ref lvItem);
|
||||
}
|
||||
|
@ -5262,13 +5370,15 @@ namespace System.Windows.Forms
|
|||
|
||||
private void SmallImageListRecreateHandle(object sender, EventArgs e)
|
||||
{
|
||||
if (IsHandleCreated)
|
||||
if (!IsHandleCreated)
|
||||
{
|
||||
IntPtr handle = (SmallImageList == null) ? IntPtr.Zero : SmallImageList.Handle;
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.SMALL, handle);
|
||||
|
||||
ForceCheckBoxUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
IntPtr handle = (SmallImageList is null) ? IntPtr.Zero : SmallImageList.Handle;
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.SMALL, handle);
|
||||
|
||||
ForceCheckBoxUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -5292,15 +5402,13 @@ namespace System.Windows.Forms
|
|||
|
||||
private void StateImageListRecreateHandle(object sender, EventArgs e)
|
||||
{
|
||||
if (IsHandleCreated)
|
||||
if (!IsHandleCreated)
|
||||
{
|
||||
IntPtr handle = IntPtr.Zero;
|
||||
if (imageListState != null)
|
||||
{
|
||||
handle = imageListState.Handle;
|
||||
}
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, handle);
|
||||
return;
|
||||
}
|
||||
|
||||
IntPtr handle = (StateImageList is null) ? IntPtr.Zero : StateImageList.Handle;
|
||||
User32.SendMessageW(this, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.STATE, handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -5444,8 +5552,9 @@ namespace System.Windows.Forms
|
|||
var lvgroup = new LVGROUPW
|
||||
{
|
||||
cbSize = (uint)sizeof(LVGROUPW),
|
||||
mask = LVGF.HEADER | LVGF.FOOTER | LVGF.ALIGN | LVGF.STATE | LVGF.SUBTITLE | LVGF.TASK | additionalMask,
|
||||
mask = LVGF.HEADER | LVGF.FOOTER | LVGF.ALIGN | LVGF.STATE | LVGF.SUBTITLE | LVGF.TASK | LVGF.TITLEIMAGE | additionalMask,
|
||||
cchHeader = header.Length,
|
||||
iTitleImage = -1,
|
||||
iGroupId = group.ID
|
||||
};
|
||||
|
||||
|
@ -5471,6 +5580,11 @@ namespace System.Windows.Forms
|
|||
break;
|
||||
}
|
||||
|
||||
if (group.TitleImageIndex != ImageList.Indexer.DefaultIndex || group.TitleImageKey != ImageList.Indexer.DefaultKey)
|
||||
{
|
||||
lvgroup.iTitleImage = group.ImageIndexer.ActualIndex;
|
||||
}
|
||||
|
||||
fixed (char* pSubtitle = subtitle)
|
||||
fixed (char* pTask = task)
|
||||
fixed (char* pHeader = header)
|
||||
|
@ -5622,7 +5736,7 @@ namespace System.Windows.Forms
|
|||
if (CheckBoxes)
|
||||
{
|
||||
ListViewHitTestInfo lvhti = HitTest(x, y);
|
||||
if (imageListState != null && imageListState.Images.Count < 2)
|
||||
if (_imageListState != null && _imageListState.Images.Count < 2)
|
||||
{
|
||||
// When the user clicks on the check box and the listView's state image list
|
||||
// does not have 2 images, comctl will give us an AttemptToDivideByZero exception.
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
@ -34,6 +33,8 @@ namespace System.Windows.Forms
|
|||
|
||||
private static int s_nextHeader = 1;
|
||||
|
||||
private ListViewGroupImageIndexer? _imageIndexer;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a ListViewGroup.
|
||||
/// </summary>
|
||||
|
@ -175,7 +176,8 @@ namespace System.Windows.Forms
|
|||
/// Controls which <see cref="ListViewGroupCollapsedState"/> the group will appear as.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// One of the <see cref="ListViewGroupCollapsedState"/> values that specifies how the group is displayed. The default is <see cref="ListViewGroupCollapsedState.Default"/>.
|
||||
/// One of the <see cref="ListViewGroupCollapsedState"/> values that specifies how the group is displayed.
|
||||
/// The default is <see cref="ListViewGroupCollapsedState.Default"/>.
|
||||
/// </value>
|
||||
/// <exception cref="InvalidEnumArgumentException">
|
||||
/// The specified value when setting this property is not a valid <see cref="ListViewGroupCollapsedState"/> value.
|
||||
|
@ -242,6 +244,79 @@ namespace System.Windows.Forms
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the index of the image that is displayed for the group.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The zero-based index of the image in the ImageList that is displayed for the group. The default is -1.
|
||||
/// </value>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// The value specified is less than -1.
|
||||
/// </exception>
|
||||
[DefaultValue(-1)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(Drawing.Design.UITypeEditor))]
|
||||
[Localizable(true)]
|
||||
[RefreshProperties(RefreshProperties.Repaint)]
|
||||
[SRCategory(nameof(SR.CatBehavior))]
|
||||
[TypeConverter(typeof(NoneExcludedImageIndexConverter))]
|
||||
public int TitleImageIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
ImageList? imageList = ImageIndexer.ImageList;
|
||||
return imageList == null || ImageIndexer.Index < imageList.Images.Count
|
||||
? ImageIndexer.Index
|
||||
: imageList.Images.Count - 1;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < ImageList.Indexer.DefaultIndex)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value,
|
||||
string.Format(SR.InvalidLowBoundArgumentEx, nameof(TitleImageIndex), value, ImageList.Indexer.DefaultIndex));
|
||||
}
|
||||
|
||||
if (ImageIndexer.Index == value && value != ImageList.Indexer.DefaultIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImageIndexer.Index = value;
|
||||
UpdateListView();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key of the image that is displayed for the group.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The key for the image that is displayed for the group.
|
||||
/// </value>
|
||||
[DefaultValue("")]
|
||||
[TypeConverter(typeof(ImageKeyConverter))]
|
||||
[Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(Drawing.Design.UITypeEditor))]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[RefreshProperties(RefreshProperties.Repaint)]
|
||||
[SRCategory(nameof(SR.CatBehavior))]
|
||||
[Localizable(true)]
|
||||
public string TitleImageKey
|
||||
{
|
||||
get => ImageIndexer.Key;
|
||||
set
|
||||
{
|
||||
if (ImageIndexer.Key == value && value != ImageList.Indexer.DefaultKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImageIndexer.Key = value;
|
||||
UpdateListView();
|
||||
}
|
||||
}
|
||||
|
||||
internal ListViewGroupImageIndexer ImageIndexer => _imageIndexer ??= new ListViewGroupImageIndexer(this);
|
||||
|
||||
internal int ID { get; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// We need a special way to defer to the ListView's image list for indexing purposes.
|
||||
/// ListViewGroupImageIndexer is a class used to support <see cref="ListViewGroup.TitleImageIndex"/> and
|
||||
/// <see cref="ListViewGroup.TitleImageKey"/>.
|
||||
/// </summary>
|
||||
internal class ListViewGroupImageIndexer : ImageList.Indexer
|
||||
{
|
||||
private readonly ListViewGroup _owner;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ListViewGroupImageIndexer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="group">The <see cref="ListViewGroup"/> that this object belongs to.</param>
|
||||
public ListViewGroupImageIndexer(ListViewGroup group)
|
||||
{
|
||||
_owner = group;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ListView.GroupImageList"/> of the <see cref="ListView"/>
|
||||
/// associated with the group.
|
||||
/// </summary>
|
||||
public override ImageList? ImageList
|
||||
{
|
||||
get => _owner.ListView?.GroupImageList;
|
||||
set => Debug.Fail("We should never set the image list");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -58,24 +58,6 @@ namespace System.Windows.Forms
|
|||
private string toolTipText = string.Empty;
|
||||
private object userData;
|
||||
|
||||
// We need a special way to defer to the ListView's image
|
||||
// list for indexing purposes.
|
||||
internal class ListViewItemImageIndexer : ImageList.Indexer
|
||||
{
|
||||
private readonly ListViewItem _owner;
|
||||
|
||||
public ListViewItemImageIndexer(ListViewItem item)
|
||||
{
|
||||
_owner = item;
|
||||
}
|
||||
|
||||
public override ImageList ImageList
|
||||
{
|
||||
get => _owner?.ImageList;
|
||||
set => Debug.Fail("We should never set the image list");
|
||||
}
|
||||
}
|
||||
|
||||
public ListViewItem()
|
||||
{
|
||||
StateSelected = false;
|
||||
|
@ -443,30 +425,28 @@ namespace System.Windows.Forms
|
|||
{
|
||||
get
|
||||
{
|
||||
if (ImageIndexer.Index != ImageList.Indexer.DefaultIndex && ImageList != null && ImageIndexer.Index >= ImageList.Images.Count)
|
||||
{
|
||||
return ImageList.Images.Count - 1;
|
||||
}
|
||||
|
||||
return ImageIndexer.Index;
|
||||
return ImageList == null || ImageIndexer.Index < ImageList.Images.Count
|
||||
? ImageIndexer.Index
|
||||
: ImageList.Images.Count - 1;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < ImageList.Indexer.DefaultIndex)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value, string.Format(SR.InvalidLowBoundArgumentEx, nameof(ImageIndex), value, ImageList.Indexer.DefaultIndex));
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value,
|
||||
string.Format(SR.InvalidLowBoundArgumentEx, nameof(ImageIndex), value, ImageList.Indexer.DefaultIndex));
|
||||
}
|
||||
|
||||
ImageIndexer.Index = value;
|
||||
|
||||
if (listView != null && listView.IsHandleCreated)
|
||||
{
|
||||
listView.SetItemImage(Index, ImageIndexer.ActualIndex);
|
||||
listView.SetItemImage(itemIndex: Index, imageIndex: ImageIndexer.ActualIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal ListViewItemImageIndexer ImageIndexer => imageIndexer ?? (imageIndexer = new ListViewItemImageIndexer(this));
|
||||
internal ListViewItemImageIndexer ImageIndexer => imageIndexer ??= new ListViewItemImageIndexer(this);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ListViewItem's currently set image index
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// We need a special way to defer to the ListView's image list for indexing purposes.
|
||||
/// ListViewItemImageIndexer is a class used to support <see cref="ListViewItem.ImageIndex"/> and
|
||||
/// <see cref="ListViewItem.ImageKey"/>.
|
||||
/// </summary>
|
||||
internal class ListViewItemImageIndexer : ImageList.Indexer
|
||||
{
|
||||
private readonly ListViewItem _owner;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ListViewItemImageIndexer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="item">The <see cref="ListViewItem"/> that this object belongs to.</param>
|
||||
public ListViewItemImageIndexer(ListViewItem item)
|
||||
{
|
||||
_owner = item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ListViewItem.ImageList"/> associated with the item.
|
||||
/// </summary>
|
||||
public override ImageList? ImageList
|
||||
{
|
||||
get => _owner.ImageList;
|
||||
set => Debug.Fail("We should never set the image list");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
@ -36,6 +37,8 @@ namespace System.Windows.Forms.Tests
|
|||
Assert.Null(group.Tag);
|
||||
Assert.Equal(ListViewGroupCollapsedState.Default, group.CollapsedState);
|
||||
Assert.Empty(group.TaskLink);
|
||||
Assert.Empty(group.TitleImageKey);
|
||||
Assert.Equal(-1, group.TitleImageIndex);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
|
@ -55,6 +58,8 @@ namespace System.Windows.Forms.Tests
|
|||
Assert.Null(group.Tag);
|
||||
Assert.Equal(ListViewGroupCollapsedState.Default, group.CollapsedState);
|
||||
Assert.Empty(group.TaskLink);
|
||||
Assert.Empty(group.TitleImageKey);
|
||||
Assert.Equal(-1, group.TitleImageIndex);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> Ctor_String_HorizontalAlignment_TestData()
|
||||
|
@ -83,6 +88,8 @@ namespace System.Windows.Forms.Tests
|
|||
Assert.Null(group.Tag);
|
||||
Assert.Equal(ListViewGroupCollapsedState.Default, group.CollapsedState);
|
||||
Assert.Empty(group.TaskLink);
|
||||
Assert.Empty(group.TitleImageKey);
|
||||
Assert.Equal(-1, group.TitleImageIndex);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> Ctor_String_String_TestData()
|
||||
|
@ -109,6 +116,278 @@ namespace System.Windows.Forms.Tests
|
|||
Assert.Null(group.Tag);
|
||||
Assert.Equal(ListViewGroupCollapsedState.Default, group.CollapsedState);
|
||||
Assert.Empty(group.TaskLink);
|
||||
Assert.Empty(group.TitleImageKey);
|
||||
Assert.Equal(-1, group.TitleImageIndex);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetNonNegativeIntTheoryData))]
|
||||
[InlineData(-1)]
|
||||
public void ListViewGroup_TitleImageIndex_SetWithoutListView_GetReturnsExpected(int value)
|
||||
{
|
||||
var group = new ListViewGroup
|
||||
{
|
||||
TitleImageIndex = value
|
||||
};
|
||||
|
||||
Assert.Equal(value, group.TitleImageIndex);
|
||||
|
||||
// Set same.
|
||||
group.TitleImageIndex = value;
|
||||
Assert.Equal(value, group.TitleImageIndex);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetNonNegativeIntTheoryData))]
|
||||
[InlineData(-1)]
|
||||
public void ListViewGroup_TitleImageIndex_SetWithListView_GetReturnsExpected(int value)
|
||||
{
|
||||
using var listView = new ListView();
|
||||
var group = new ListViewGroup();
|
||||
listView.Groups.Add(group);
|
||||
|
||||
group.TitleImageIndex = value;
|
||||
Assert.Equal(value, group.TitleImageIndex);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
|
||||
// Set same.
|
||||
group.TitleImageIndex = value;
|
||||
Assert.Equal(value, group.TitleImageIndex);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetNonNegativeIntTheoryData))]
|
||||
[InlineData(-1)]
|
||||
public void ListViewGroup_TitleImageIndex_SetWithListViewWithHandle_GetReturnsExpected(int value)
|
||||
{
|
||||
using var listView = new ListView();
|
||||
var group = new ListViewGroup();
|
||||
listView.Groups.Add(group);
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
int invalidatedCallCount = 0;
|
||||
listView.Invalidated += (sender, e) => invalidatedCallCount++;
|
||||
int styleChangedCallCount = 0;
|
||||
listView.StyleChanged += (sender, e) => styleChangedCallCount++;
|
||||
int createdCallCount = 0;
|
||||
listView.HandleCreated += (sender, e) => createdCallCount++;
|
||||
|
||||
group.TitleImageIndex = value;
|
||||
Assert.Equal(value, group.TitleImageIndex);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
|
||||
// Set same.
|
||||
group.TitleImageIndex = value;
|
||||
Assert.Equal(value, group.TitleImageIndex);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
}
|
||||
|
||||
// Need to verify test once RE fixed.
|
||||
[WinFormsFact(Skip = "Crash with AbandonedMutexException. See: https://github.com/dotnet/arcade/issues/5325")]
|
||||
public unsafe void ListViewGroup_TitleImageIndex_GetGroupInfo_Success()
|
||||
{
|
||||
// Run this from another thread as we call Application.EnableVisualStyles.
|
||||
using RemoteInvokeHandle invokerHandle = RemoteExecutor.Invoke(() =>
|
||||
{
|
||||
var data = new (int, int)[] { (-1, -1), (0 , 0), (1, 1), (2, -1) };
|
||||
foreach ((int Index, int Expected) value in data)
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
|
||||
using var listView = new ListView();
|
||||
|
||||
using var groupImageList = new ImageList();
|
||||
groupImageList.Images.Add(new Bitmap(10, 10));
|
||||
groupImageList.Images.Add(new Bitmap(20, 20));
|
||||
listView.GroupImageList = groupImageList;
|
||||
Assert.Equal(groupImageList.Handle,
|
||||
User32.SendMessageW(listView.Handle, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.GROUPHEADER, groupImageList.Handle));
|
||||
|
||||
var group = new ListViewGroup();
|
||||
listView.Groups.Add(group);
|
||||
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
group.TitleImageIndex = value.Index;
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPCOUNT, IntPtr.Zero, IntPtr.Zero));
|
||||
var lvgroup = new LVGROUPW
|
||||
{
|
||||
cbSize = (uint)sizeof(LVGROUPW),
|
||||
mask = LVGF.TITLEIMAGE | LVGF.GROUPID,
|
||||
};
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPINFOBYINDEX, (IntPtr)0, ref lvgroup));
|
||||
Assert.Equal(value.Expected, lvgroup.iTitleImage);
|
||||
Assert.True(lvgroup.iGroupId >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
// verify the remote process succeeded
|
||||
Assert.Equal(0, invokerHandle.ExitCode);
|
||||
}
|
||||
|
||||
[WinFormsFact]
|
||||
public void ListViewGroup_TitleImageIndex_SetInvalid_ThrowsArgumentOutOfRangeException()
|
||||
{
|
||||
var random = new Random();
|
||||
int value = random.Next(2, int.MaxValue) * -1;
|
||||
var group = new ListViewGroup();
|
||||
Assert.Throws<ArgumentOutOfRangeException>("value", () => group.TitleImageIndex = value);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))]
|
||||
public void ListViewGroup_TitleImageIndex_SetTitleImageKey_GetReturnsExpected(string key, string expected)
|
||||
{
|
||||
var group = new ListViewGroup
|
||||
{
|
||||
TitleImageIndex = 0
|
||||
};
|
||||
|
||||
Assert.Equal(0, group.TitleImageIndex);
|
||||
|
||||
// verify TitleImageIndex resets to default once TitleImageKey is set
|
||||
group.TitleImageKey = key;
|
||||
Assert.Equal(expected, group.TitleImageKey);
|
||||
Assert.Equal(ImageList.Indexer.DefaultIndex, group.TitleImageIndex);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))]
|
||||
[InlineData("te\0xt", "te\0xt")]
|
||||
public void ListViewGroup_TitleImageKey_SetWithoutListView_GetReturnsExpected(string value, string expected)
|
||||
{
|
||||
var group = new ListViewGroup
|
||||
{
|
||||
TitleImageKey = value
|
||||
};
|
||||
|
||||
Assert.Equal(expected, group.TitleImageKey);
|
||||
|
||||
// Set same.
|
||||
group.TitleImageKey = value;
|
||||
Assert.Equal(expected, group.TitleImageKey);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))]
|
||||
[InlineData("te\0xt", "te\0xt")]
|
||||
public void ListViewGroup_TitleImageKey_SetWithListView_GetReturnsExpected(string value, string expected)
|
||||
{
|
||||
using var listView = new ListView();
|
||||
var group = new ListViewGroup();
|
||||
listView.Groups.Add(group);
|
||||
|
||||
group.TitleImageKey = value;
|
||||
Assert.Equal(expected, group.TitleImageKey);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
|
||||
// Set same.
|
||||
group.TitleImageKey = value;
|
||||
Assert.Equal(expected, group.TitleImageKey);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[InlineData(null, "")]
|
||||
[InlineData("", "")]
|
||||
[InlineData("header", "header")]
|
||||
[InlineData("te\0xt", "te\0xt")]
|
||||
[InlineData("ListViewGroup", "ListViewGroup")]
|
||||
public void ListViewGroup_TitleImageKey_SetWithListViewWithHandle_GetReturnsExpected(string value, string expected)
|
||||
{
|
||||
using var listView = new ListView();
|
||||
var group = new ListViewGroup();
|
||||
listView.Groups.Add(group);
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
int invalidatedCallCount = 0;
|
||||
listView.Invalidated += (sender, e) => invalidatedCallCount++;
|
||||
int styleChangedCallCount = 0;
|
||||
listView.StyleChanged += (sender, e) => styleChangedCallCount++;
|
||||
int createdCallCount = 0;
|
||||
listView.HandleCreated += (sender, e) => createdCallCount++;
|
||||
|
||||
group.TitleImageKey = value;
|
||||
Assert.Equal(expected, group.TitleImageKey);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
|
||||
// Set same.
|
||||
group.TitleImageKey = value;
|
||||
Assert.Equal(expected, group.TitleImageKey);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
}
|
||||
|
||||
// Need to verify test once RE fixed.
|
||||
[WinFormsFact(Skip = "Crash with AbandonedMutexException. See: https://github.com/dotnet/arcade/issues/5325")]
|
||||
public unsafe void ListViewGroup_TitleImageKey_GetGroupInfo_Success()
|
||||
{
|
||||
// Run this from another thread as we call Application.EnableVisualStyles.
|
||||
using RemoteInvokeHandle invokerHandle = RemoteExecutor.Invoke(() =>
|
||||
{
|
||||
var data = new (string, int)[] { (null, -1), (string.Empty, -1), ("text", 0), ("te\0t", 0) };
|
||||
foreach ((string Key, int ExpectedIndex) value in data)
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
|
||||
using var listView = new ListView();
|
||||
|
||||
using var groupImageList = new ImageList();
|
||||
groupImageList.Images.Add(value.Key, new Bitmap(10, 10));
|
||||
listView.GroupImageList = groupImageList;
|
||||
Assert.Equal(groupImageList.Handle,
|
||||
User32.SendMessageW(listView.Handle, (User32.WM)LVM.SETIMAGELIST, (IntPtr)LVSIL.GROUPHEADER, groupImageList.Handle));
|
||||
|
||||
var group = new ListViewGroup();
|
||||
listView.Groups.Add(group);
|
||||
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
group.TitleImageKey = value.Key;
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPCOUNT, IntPtr.Zero, IntPtr.Zero));
|
||||
var lvgroup = new LVGROUPW
|
||||
{
|
||||
cbSize = (uint)sizeof(LVGROUPW),
|
||||
mask = LVGF.TITLEIMAGE | LVGF.GROUPID
|
||||
};
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPINFOBYINDEX, (IntPtr)0, ref lvgroup));
|
||||
Assert.Equal(value.ExpectedIndex, lvgroup.iTitleImage);
|
||||
Assert.True(lvgroup.iGroupId >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
// verify the remote process succeeded
|
||||
Assert.Equal(0, invokerHandle.ExitCode);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetNonNegativeIntTheoryData))]
|
||||
[InlineData(-1)]
|
||||
public void ListViewGroup_TitleImageKey_SetTitleImageIndex_GetReturnsExpected(int value)
|
||||
{
|
||||
var group = new ListViewGroup
|
||||
{
|
||||
TitleImageKey = "key"
|
||||
};
|
||||
|
||||
Assert.Equal("key", group.TitleImageKey);
|
||||
|
||||
// verify TitleImageKey resets to default once TitleImageIndex is set
|
||||
group.TitleImageIndex = value;
|
||||
Assert.Equal(value, group.TitleImageIndex);
|
||||
Assert.Equal(ImageList.Indexer.DefaultKey, group.TitleImageKey);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
|
@ -120,6 +399,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Subtitle = value
|
||||
};
|
||||
|
||||
Assert.Equal(expected, group.Subtitle);
|
||||
|
||||
// Set same.
|
||||
|
@ -218,6 +498,7 @@ namespace System.Windows.Forms.Tests
|
|||
pszSubtitle = buffer,
|
||||
cchSubtitle = 256
|
||||
};
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPINFOBYINDEX, (IntPtr)0, ref lvgroup));
|
||||
Assert.Equal(expected, new string(lvgroup.pszSubtitle));
|
||||
Assert.True(lvgroup.iGroupId >= 0);
|
||||
|
@ -237,6 +518,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Footer = value
|
||||
};
|
||||
|
||||
Assert.Equal(expected, group.Footer);
|
||||
|
||||
// Set same.
|
||||
|
@ -327,6 +609,7 @@ namespace System.Windows.Forms.Tests
|
|||
pszFooter = buffer,
|
||||
cchFooter = 256
|
||||
};
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPINFOBYINDEX, (IntPtr)0, ref lvgroup));
|
||||
Assert.Equal(expected, new string(lvgroup.pszFooter));
|
||||
Assert.True(lvgroup.iGroupId >= 0);
|
||||
|
@ -357,6 +640,7 @@ namespace System.Windows.Forms.Tests
|
|||
Footer = footer,
|
||||
FooterAlignment = value
|
||||
};
|
||||
|
||||
Assert.Equal(value, group.FooterAlignment);
|
||||
Assert.Equal(expectedFooter, group.Footer);
|
||||
|
||||
|
@ -375,6 +659,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Footer = footer
|
||||
};
|
||||
|
||||
listView.Groups.Add(group);
|
||||
|
||||
group.FooterAlignment = value;
|
||||
|
@ -398,6 +683,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Footer = footer
|
||||
};
|
||||
|
||||
listView.Groups.Add(group);
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
int invalidatedCallCount = 0;
|
||||
|
@ -452,6 +738,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Footer = footer
|
||||
};
|
||||
|
||||
listView.Groups.Add(group1);
|
||||
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
|
@ -466,6 +753,7 @@ namespace System.Windows.Forms.Tests
|
|||
pszFooter = buffer,
|
||||
cchFooter = 256
|
||||
};
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPINFOBYINDEX, (IntPtr)0, ref lvgroup));
|
||||
Assert.Equal(footer, new string(lvgroup.pszFooter));
|
||||
Assert.True(lvgroup.iGroupId >= 0);
|
||||
|
@ -490,6 +778,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Header = value
|
||||
};
|
||||
|
||||
Assert.Equal(expected, group.Header);
|
||||
|
||||
// Set same.
|
||||
|
@ -580,6 +869,7 @@ namespace System.Windows.Forms.Tests
|
|||
pszHeader = buffer,
|
||||
cchHeader = 256
|
||||
};
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPINFOBYINDEX, (IntPtr)0, ref lvgroup));
|
||||
Assert.Equal(expected, new string(lvgroup.pszHeader));
|
||||
Assert.True(lvgroup.iGroupId >= 0);
|
||||
|
@ -600,6 +890,7 @@ namespace System.Windows.Forms.Tests
|
|||
Header = header,
|
||||
HeaderAlignment = value
|
||||
};
|
||||
|
||||
Assert.Equal(value, group.HeaderAlignment);
|
||||
Assert.Equal(expectedHeader, group.Header);
|
||||
|
||||
|
@ -618,6 +909,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Header = header
|
||||
};
|
||||
|
||||
listView.Groups.Add(group);
|
||||
|
||||
group.HeaderAlignment = value;
|
||||
|
@ -641,6 +933,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Header = header
|
||||
};
|
||||
|
||||
listView.Groups.Add(group);
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
int invalidatedCallCount = 0;
|
||||
|
@ -695,6 +988,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Header = header
|
||||
};
|
||||
|
||||
listView.Groups.Add(group1);
|
||||
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
|
@ -709,6 +1003,7 @@ namespace System.Windows.Forms.Tests
|
|||
pszHeader = buffer,
|
||||
cchHeader = 256
|
||||
};
|
||||
|
||||
Assert.Equal((IntPtr)1, User32.SendMessageW(listView.Handle, (User32.WM)LVM.GETGROUPINFOBYINDEX, (IntPtr)0, ref lvgroup));
|
||||
Assert.Equal(header, new string(lvgroup.pszHeader));
|
||||
Assert.True(lvgroup.iGroupId >= 0);
|
||||
|
@ -868,6 +1163,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Name = value
|
||||
};
|
||||
|
||||
Assert.Same(value, group.Name);
|
||||
|
||||
// Set same.
|
||||
|
@ -994,6 +1290,7 @@ namespace System.Windows.Forms.Tests
|
|||
{
|
||||
Tag = value
|
||||
};
|
||||
|
||||
Assert.Same(value, group.Tag);
|
||||
|
||||
// Set same.
|
||||
|
|
|
@ -88,6 +88,7 @@ namespace System.Windows.Forms.Tests
|
|||
Assert.False(control.GridLines);
|
||||
Assert.Empty(control.Groups);
|
||||
Assert.Same(control.Groups, control.Groups);
|
||||
Assert.Null(control.GroupImageList);
|
||||
Assert.False(control.HasChildren);
|
||||
Assert.Equal(ColumnHeaderStyle.Clickable, control.HeaderStyle);
|
||||
Assert.Equal(97, control.Height);
|
||||
|
@ -1518,6 +1519,320 @@ namespace System.Windows.Forms.Tests
|
|||
Assert.Equal(0, createdCallCount);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GroupImageList_Set_GetReturnsExpected()
|
||||
{
|
||||
var nonEmptyImageList = new ImageList();
|
||||
nonEmptyImageList.Images.Add(new Bitmap(10, 10));
|
||||
|
||||
foreach (bool autoArrange in new bool[] { true, false })
|
||||
{
|
||||
foreach (bool virtualMode in new bool[] { true, false })
|
||||
{
|
||||
foreach (View view in new View[] { View.Details, View.LargeIcon, View.List, View.SmallIcon })
|
||||
{
|
||||
yield return new object[] { autoArrange, virtualMode, view, null };
|
||||
yield return new object[] { autoArrange, virtualMode, view, new ImageList() };
|
||||
yield return new object[] { autoArrange, virtualMode, view, nonEmptyImageList };
|
||||
}
|
||||
}
|
||||
|
||||
yield return new object[] { autoArrange, false, View.Tile, null };
|
||||
yield return new object[] { autoArrange, false, View.Tile, new ImageList() };
|
||||
yield return new object[] { autoArrange, false, View.Tile, nonEmptyImageList };
|
||||
}
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[MemberData(nameof(GroupImageList_Set_GetReturnsExpected))]
|
||||
public void ListView_GroupImageList_Set_GetReturnsExpected(bool autoArrange, bool virtualMode, View view, ImageList value)
|
||||
{
|
||||
using var listView = new ListView
|
||||
{
|
||||
AutoArrange = autoArrange,
|
||||
VirtualMode = virtualMode,
|
||||
View = view,
|
||||
GroupImageList = value
|
||||
};
|
||||
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
|
||||
// Set same.
|
||||
listView.GroupImageList = value;
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[MemberData(nameof(GroupImageList_Set_GetReturnsExpected))]
|
||||
public void ListView_GroupImageList_SetWithNonNullOldValue_GetReturnsExpected(bool autoArrange, bool virtualMode, View view, ImageList value)
|
||||
{
|
||||
using var imageList = new ImageList();
|
||||
using var listView = new ListView
|
||||
{
|
||||
AutoArrange = autoArrange,
|
||||
VirtualMode = virtualMode,
|
||||
View = view,
|
||||
GroupImageList = imageList
|
||||
};
|
||||
|
||||
listView.GroupImageList = value;
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
|
||||
// Set same.
|
||||
listView.GroupImageList = value;
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GroupImageList_SetWithHandle_GetReturnsExpected()
|
||||
{
|
||||
var nonEmptyImageList = new ImageList();
|
||||
nonEmptyImageList.Images.Add(new Bitmap(10, 10));
|
||||
|
||||
yield return new object[] { true, false, View.Details, null };
|
||||
yield return new object[] { true, false, View.Details, new ImageList() };
|
||||
yield return new object[] { true, false, View.Details, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.LargeIcon, null };
|
||||
yield return new object[] { true, false, View.LargeIcon, new ImageList() };
|
||||
yield return new object[] { true, false, View.LargeIcon, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.List, null };
|
||||
yield return new object[] { true, false, View.List, new ImageList() };
|
||||
yield return new object[] { true, false, View.List, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.SmallIcon, null };
|
||||
yield return new object[] { true, false, View.SmallIcon, new ImageList() };
|
||||
yield return new object[] { true, false, View.SmallIcon, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.Tile, null };
|
||||
yield return new object[] { true, false, View.Tile, new ImageList() };
|
||||
yield return new object[] { true, false, View.Tile, nonEmptyImageList };
|
||||
|
||||
foreach (bool autoArrange in new bool[] { true, false })
|
||||
{
|
||||
yield return new object[] { autoArrange, true, View.Details, null };
|
||||
yield return new object[] { autoArrange, true, View.Details, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.Details, nonEmptyImageList };
|
||||
yield return new object[] { autoArrange, true, View.LargeIcon, null };
|
||||
yield return new object[] { autoArrange, true, View.LargeIcon, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.LargeIcon, nonEmptyImageList };
|
||||
yield return new object[] { autoArrange, true, View.List, null };
|
||||
yield return new object[] { autoArrange, true, View.List, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.List, nonEmptyImageList };
|
||||
yield return new object[] { autoArrange, true, View.SmallIcon, null };
|
||||
yield return new object[] { autoArrange, true, View.SmallIcon, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.SmallIcon, nonEmptyImageList };
|
||||
}
|
||||
|
||||
yield return new object[] { false, false, View.Details, null };
|
||||
yield return new object[] { false, false, View.Details, new ImageList() };
|
||||
yield return new object[] { false, false, View.Details, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.LargeIcon, null };
|
||||
yield return new object[] { false, false, View.LargeIcon, new ImageList() };
|
||||
yield return new object[] { false, false, View.LargeIcon, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.List, null };
|
||||
yield return new object[] { false, false, View.List, new ImageList() };
|
||||
yield return new object[] { false, false, View.List, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.SmallIcon, null };
|
||||
yield return new object[] { false, false, View.SmallIcon, new ImageList() };
|
||||
yield return new object[] { false, false, View.SmallIcon, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.Tile, null };
|
||||
yield return new object[] { false, false, View.Tile, new ImageList() };
|
||||
yield return new object[] { false, false, View.Tile, nonEmptyImageList };
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[MemberData(nameof(GroupImageList_SetWithHandle_GetReturnsExpected))]
|
||||
public void ListView_GroupImageList_SetWithHandle_GetReturnsExpected(bool autoArrange, bool virtualMode, View view, ImageList value)
|
||||
{
|
||||
using var listView = new ListView
|
||||
{
|
||||
AutoArrange = autoArrange,
|
||||
VirtualMode = virtualMode,
|
||||
View = view
|
||||
};
|
||||
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
int invalidatedCallCount = 0;
|
||||
listView.Invalidated += (sender, e) => invalidatedCallCount++;
|
||||
int styleChangedCallCount = 0;
|
||||
listView.StyleChanged += (sender, e) => styleChangedCallCount++;
|
||||
int createdCallCount = 0;
|
||||
listView.HandleCreated += (sender, e) => createdCallCount++;
|
||||
|
||||
listView.GroupImageList = value;
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
|
||||
// Set same.
|
||||
listView.GroupImageList = value;
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GroupImageList_SetWithHandleWithNonNullOldValue_GetReturnsExpected()
|
||||
{
|
||||
var nonEmptyImageList = new ImageList();
|
||||
nonEmptyImageList.Images.Add(new Bitmap(10, 10));
|
||||
|
||||
yield return new object[] { true, false, View.Details, null };
|
||||
yield return new object[] { true, false, View.Details, new ImageList() };
|
||||
yield return new object[] { true, false, View.Details, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.LargeIcon, null };
|
||||
yield return new object[] { true, false, View.LargeIcon, new ImageList() };
|
||||
yield return new object[] { true, false, View.LargeIcon, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.List, null };
|
||||
yield return new object[] { true, false, View.List, new ImageList() };
|
||||
yield return new object[] { true, false, View.List, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.SmallIcon, null };
|
||||
yield return new object[] { true, false, View.SmallIcon, new ImageList() };
|
||||
yield return new object[] { true, false, View.SmallIcon, nonEmptyImageList };
|
||||
yield return new object[] { true, false, View.Tile, null };
|
||||
yield return new object[] { true, false, View.Tile, new ImageList() };
|
||||
yield return new object[] { true, false, View.Tile, nonEmptyImageList };
|
||||
|
||||
foreach (bool autoArrange in new bool[] { true, false })
|
||||
{
|
||||
yield return new object[] { autoArrange, true, View.Details, null };
|
||||
yield return new object[] { autoArrange, true, View.Details, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.Details, nonEmptyImageList };
|
||||
yield return new object[] { autoArrange, true, View.LargeIcon, null };
|
||||
yield return new object[] { autoArrange, true, View.LargeIcon, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.LargeIcon, nonEmptyImageList };
|
||||
yield return new object[] { autoArrange, true, View.List, null };
|
||||
yield return new object[] { autoArrange, true, View.List, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.List, nonEmptyImageList };
|
||||
yield return new object[] { autoArrange, true, View.SmallIcon, null };
|
||||
yield return new object[] { autoArrange, true, View.SmallIcon, new ImageList() };
|
||||
yield return new object[] { autoArrange, true, View.SmallIcon, nonEmptyImageList };
|
||||
}
|
||||
|
||||
yield return new object[] { false, false, View.Details, null };
|
||||
yield return new object[] { false, false, View.Details, new ImageList() };
|
||||
yield return new object[] { false, false, View.Details, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.LargeIcon, null };
|
||||
yield return new object[] { false, false, View.LargeIcon, new ImageList() };
|
||||
yield return new object[] { false, false, View.LargeIcon, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.List, null };
|
||||
yield return new object[] { false, false, View.List, new ImageList() };
|
||||
yield return new object[] { false, false, View.List, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.SmallIcon, null };
|
||||
yield return new object[] { false, false, View.SmallIcon, new ImageList() };
|
||||
yield return new object[] { false, false, View.SmallIcon, nonEmptyImageList };
|
||||
yield return new object[] { false, false, View.Tile, null };
|
||||
yield return new object[] { false, false, View.Tile, new ImageList() };
|
||||
yield return new object[] { false, false, View.Tile, nonEmptyImageList };
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[MemberData(nameof(GroupImageList_SetWithHandleWithNonNullOldValue_GetReturnsExpected))]
|
||||
public void ListView_GroupImageList_SetWithHandleWithNonNullOldValue_GetReturnsExpected(bool autoArrange, bool virtualMode, View view, ImageList value)
|
||||
{
|
||||
using var listView = new ListView
|
||||
{
|
||||
AutoArrange = autoArrange,
|
||||
VirtualMode = virtualMode,
|
||||
View = view,
|
||||
GroupImageList = new ImageList()
|
||||
};
|
||||
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
int invalidatedCallCount = 0;
|
||||
listView.Invalidated += (sender, e) => invalidatedCallCount++;
|
||||
int styleChangedCallCount = 0;
|
||||
listView.StyleChanged += (sender, e) => styleChangedCallCount++;
|
||||
int createdCallCount = 0;
|
||||
listView.HandleCreated += (sender, e) => createdCallCount++;
|
||||
|
||||
listView.GroupImageList = value;
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
|
||||
// Set same.
|
||||
listView.GroupImageList = value;
|
||||
Assert.Same(value, listView.GroupImageList);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))]
|
||||
public void ListView_GroupImageList_Dispose_DetachesFromListView(bool autoArrange)
|
||||
{
|
||||
using var imageList1 = new ImageList();
|
||||
using var imageList2 = new ImageList();
|
||||
using var listView = new ListView
|
||||
{
|
||||
AutoArrange = autoArrange,
|
||||
GroupImageList = imageList1
|
||||
};
|
||||
|
||||
Assert.Same(imageList1, listView.GroupImageList);
|
||||
|
||||
imageList1.Dispose();
|
||||
Assert.Null(listView.GroupImageList);
|
||||
Assert.False(listView.IsHandleCreated);
|
||||
|
||||
// Make sure we detached the setter.
|
||||
listView.GroupImageList = imageList2;
|
||||
imageList1.Dispose();
|
||||
Assert.Same(imageList2, listView.GroupImageList);
|
||||
}
|
||||
|
||||
[WinFormsTheory]
|
||||
[InlineData(true, 1)]
|
||||
[InlineData(false, 0)]
|
||||
public void ListView_GroupImageList_DisposeWithHandle_DetachesFromListView(bool autoArrange, int expectedInvalidatedCallCount)
|
||||
{
|
||||
using var imageList1 = new ImageList();
|
||||
using var imageList2 = new ImageList();
|
||||
using var listView = new ListView
|
||||
{
|
||||
AutoArrange = autoArrange
|
||||
};
|
||||
|
||||
Assert.NotEqual(IntPtr.Zero, listView.Handle);
|
||||
int invalidatedCallCount = 0;
|
||||
listView.Invalidated += (sender, e) => invalidatedCallCount++;
|
||||
int styleChangedCallCount = 0;
|
||||
listView.StyleChanged += (sender, e) => styleChangedCallCount++;
|
||||
int createdCallCount = 0;
|
||||
listView.HandleCreated += (sender, e) => createdCallCount++;
|
||||
|
||||
listView.GroupImageList = imageList1;
|
||||
Assert.Same(imageList1, listView.GroupImageList);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(0, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
|
||||
imageList1.Dispose();
|
||||
Assert.Null(listView.GroupImageList);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(expectedInvalidatedCallCount, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
|
||||
// Make sure we detached the setter.
|
||||
listView.GroupImageList = imageList2;
|
||||
imageList1.Dispose();
|
||||
Assert.Same(imageList2, listView.GroupImageList);
|
||||
Assert.True(listView.IsHandleCreated);
|
||||
Assert.Equal(expectedInvalidatedCallCount, invalidatedCallCount);
|
||||
Assert.Equal(0, styleChangedCallCount);
|
||||
Assert.Equal(0, createdCallCount);
|
||||
}
|
||||
|
||||
[WinFormsFact]
|
||||
public void ListView_Handle_GetWithBackColor_Success()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче