2 // System.Windows.Forms.ImageList.cs
5 // Peter Bartok <pbartok@novell.com>
6 // Kornél Pál <http://www.kornelpal.hu/>
8 // Copyright (C) 2004-2005 Novell, Inc.
9 // Copyright (C) 2005 Kornél Pál
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 // Differences between MS.NET ImageList and this implementation:
38 // This is a fully managed image list implementation.
40 // Images are stored as Format32bppArgb internally but ColorDepth is applied
41 // to the colors of images. Images[index] returns a Format32bppArgb copy of
42 // the image so this difference is only internal.
44 // MS.NET has no alpha channel support (except for icons in 32-bit mode with
45 // comctl32.dll version 6.0) but this implementation has full alpha channel
46 // support in 32-bit mode.
48 // Handle should be an HIMAGELIST returned by ImageList_Create. This
49 // implementation uses (IntPtr)(-1) that is a non-zero but invalid handle.
51 // MS.NET destroys handles using the garbage collector this implementation
52 // does the same with Image objects stored in an ArrayList.
54 // MS.NET 1.x shares the same HIMAGELIST between ImageLists that were
55 // initialized from the same ImageListStreamer and doesn't update ImageSize
56 // and ColorDepth that are treated as bugs and MS.NET 2.0 behavior is
59 // MS.NET 2.0 does not clear keys when handle is destroyed that is treated as
63 using System
.Collections
;
64 using System
.Collections
.Specialized
;
65 using System
.ComponentModel
;
66 using System
.ComponentModel
.Design
.Serialization
;
68 using System
.Drawing
.Design
;
69 using System
.Drawing
.Imaging
;
70 using System
.Globalization
;
71 using System
.Runtime
.InteropServices
;
73 namespace System
.Windows
.Forms
75 [DefaultProperty("Images")]
76 [Designer("System.Windows.Forms.Design.ImageListDesigner, " + Consts
.AssemblySystem_Design
)]
78 [DesignerSerializer("System.Windows.Forms.Design.ImageListCodeDomSerializer, " + Consts
.AssemblySystem_Design
, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts
.AssemblySystem_Design
)]
80 [ToolboxItemFilter("System.Windows.Forms")]
81 [TypeConverter(typeof(ImageListConverter
))]
82 public sealed class ImageList
: System
.ComponentModel
.Component
84 #region Private Fields
85 private const ColorDepth DefaultColorDepth
= ColorDepth
.Depth8Bit
;
86 private static readonly Size DefaultImageSize
= new Size(16, 16);
87 private static readonly Color DefaultTransparentColor
= Color
.Transparent
;
92 private readonly ImageCollection images
;
93 #endregion // Private Fields
96 [Editor("System.Windows.Forms.Design.ImageCollectionEditor, " + Consts
.AssemblySystem_Design
, typeof(UITypeEditor
))]
97 public sealed class ImageCollection
: IList
, ICollection
, IEnumerable
99 private const int AlphaMask
= unchecked((int)0xFF000000);
107 class IndexedColorDepths
110 private IndexedColorDepths()
114 internal static readonly ColorPalette Palette4Bit
;
115 internal static readonly ColorPalette Palette8Bit
;
116 private static readonly int[] squares
;
118 static IndexedColorDepths()
123 bitmap
= new Bitmap(1, 1, PixelFormat
.Format4bppIndexed
);
124 Palette4Bit
= bitmap
.Palette
;
127 bitmap
= new Bitmap(1, 1, PixelFormat
.Format8bppIndexed
);
128 Palette8Bit
= bitmap
.Palette
;
131 squares
= new int[511];
132 for (index
= 0; index
< 256; index
++)
133 squares
[255 + index
] = squares
[255 - index
] = index
* index
;
136 internal static int GetNearestColor(Color
[] palette
, int color
)
147 count
= palette
.Length
;
148 for (index
= 0; index
< count
; index
++)
149 if (palette
[index
].ToArgb() == color
)
152 red
= unchecked((int)(unchecked((uint)color
) >> 16) & 0xFF);
153 green
= unchecked((int)(unchecked((uint)color
) >> 8) & 0xFF);
155 nearestColor
= AlphaMask
;
156 minDistance
= int.MaxValue
;
158 for (index
= 0; index
< count
; index
++)
159 if ((distance
= squares
[255 + palette
[index
].R
- red
] + squares
[255 + palette
[index
].G
- green
] + squares
[255 + palette
[index
].B
- blue
]) < minDistance
) {
160 nearestColor
= palette
[index
].ToArgb();
161 minDistance
= distance
;
169 private enum ItemFlags
172 UseTransparentColor
= 1,
176 private sealed class ImageListItem
178 internal readonly object Image
;
179 internal readonly ItemFlags Flags
;
180 internal readonly Color TransparentColor
;
181 internal readonly int ImageCount
= 1;
183 internal ImageListItem(Icon
value)
186 throw new ArgumentNullException("value");
189 this.Image
= (Icon
)value.Clone();
192 internal ImageListItem(Image
value)
195 throw new ArgumentNullException("value");
197 if (!(value is Bitmap
))
198 throw new ArgumentException("Image must be a Bitmap.");
200 // Images are not cloned.
204 internal ImageListItem(Image
value, Color transparentColor
) : this(value)
206 this.Flags
= ItemFlags
.UseTransparentColor
;
207 this.TransparentColor
= transparentColor
;
210 internal ImageListItem(Image
value, int imageCount
) : this(value)
212 this.Flags
= ItemFlags
.ImageStrip
;
213 this.ImageCount
= imageCount
;
217 #region ImageCollection Private Fields
218 private ColorDepth colorDepth
= DefaultColorDepth
;
219 private Size imageSize
= DefaultImageSize
;
220 private Color transparentColor
= DefaultTransparentColor
;
221 private ArrayList list
= new ArrayList();
223 private ArrayList keys
= new ArrayList();
226 private bool handleCreated
;
228 private int lastKeyIndex
= -1;
230 private readonly ImageList owner
;
231 #endregion // ImageCollection Private Fields
233 #region ImageCollection Internal Constructors
234 // For use in ImageList
235 internal ImageCollection(ImageList owner
)
239 #endregion // ImageCollection Internal Constructor
241 #region ImageCollection Internal Instance Properties
242 // For use in ImageList
243 internal ColorDepth ColorDepth
{
245 return this.colorDepth
;
249 if (!Enum
.IsDefined(typeof(ColorDepth
), value))
250 throw new InvalidEnumArgumentException("value", (int)value, typeof(ColorDepth
));
252 if (this.colorDepth
!= value) {
253 this.colorDepth
= value;
259 // For use in ImageList
260 internal IntPtr Handle
{
267 // For use in ImageList
268 internal bool HandleCreated
{
270 return this.handleCreated
;
274 // For use in ImageList
275 internal Size ImageSize
{
277 return this.imageSize
;
281 if (value.Width
< 1 || value.Width
> 256 || value.Height
< 1 || value.Height
> 256)
282 throw new ArgumentException("ImageSize.Width and Height must be between 1 and 256", "value");
284 if (this.imageSize
!= value) {
285 this.imageSize
= value;
291 // For use in ImageList
292 internal ImageListStreamer ImageStream
{
294 return this.Empty
? null : new ImageListStreamer(this);
299 Image
[] streamImages
;
303 if (this.handleCreated
)
309 // Only deserialized ImageListStreamers are used.
310 else if ((streamImages
= value.Images
) != null) {
311 this.list
= new ArrayList(streamImages
.Length
);
313 this.handleCreated
= true;
315 this.keys
= new ArrayList(streamImages
.Length
);
318 for (index
= 0; index
< streamImages
.Length
; index
++) {
319 list
.Add((Image
)streamImages
[index
].Clone());
325 // Invalid ColorDepth values are ignored.
326 if (Enum
.IsDefined(typeof(ColorDepth
), value.ColorDepth
))
327 this.colorDepth
= (ColorDepth
)value.ColorDepth
;
328 this.imageSize
= value.ImageSize
;
331 // Event is raised even when handle was not created yet.
332 owner
.OnRecreateHandle();
338 // For use in ImageList
339 internal Color TransparentColor
{
341 return this.transparentColor
;
345 this.transparentColor
= value;
348 #endregion // ImageCollection Internal Instance Properties
350 #region ImageCollection Public Instance Properties
354 return this.handleCreated
? list
.Count
: this.count
;
360 return this.Count
== 0;
364 public bool IsReadOnly
{
371 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
372 public Image
this[int index
] {
374 return (Image
)GetImage(index
).Clone();
380 if (index
< 0 || index
>= this.Count
)
381 throw new ArgumentOutOfRangeException("index");
384 throw new ArgumentNullException("value");
386 if (!(value is Bitmap
))
387 throw new ArgumentException("Image must be a Bitmap.");
389 image
= CreateImage(value, this.transparentColor
);
396 public Image
this[string key
] {
400 return (index
= IndexOfKey(key
)) == -1 ? null : this[index
];
404 public StringCollection Keys
{
408 StringCollection keyCollection
;
410 // Returns all keys even when there are more keys than
411 // images. Null keys are returned as empty strings.
413 keyCollection
= new StringCollection();
414 for (index
= 0; index
< keys
.Count
; index
++)
415 keyCollection
.Add(((key
= (string)keys
[index
]) == null || key
.Length
== 0) ? string.Empty
: key
);
417 return keyCollection
;
421 #endregion // ImageCollection Public Instance Properties
423 #region ImageCollection Private Static Methods
425 private static bool CompareKeys(string key1
, string key2
)
427 // Keys are case-insensitive and keys with different length
428 // are not equal even when string.Compare treats them equal.
430 if (key1
== null || key2
== null || key1
.Length
!= key2
.Length
)
433 return string.Compare(key1
, key2
, true, CultureInfo
.InvariantCulture
) == 0;
436 #endregion // ImageCollection Private Static Methods
438 #region ImageCollection Private Instance Methods
440 private int AddItem(string key
, ImageListItem item
)
442 private int AddItem(ImageListItem item
)
450 if (this.handleCreated
)
451 itemIndex
= AddItemInternal(item
);
453 // Image strips are counted as a single item in the return
454 // value of Add and AddStrip until handle is created.
456 itemIndex
= list
.Add(item
);
457 this.count
+= item
.ImageCount
;
461 if ((item
.Flags
& ItemFlags
.ImageStrip
) == 0)
464 for (index
= 0; index
< item
.ImageCount
; index
++)
471 internal event EventHandler Changed
;
473 private int AddItemInternal(ImageListItem item
)
476 Changed (this, EventArgs
.Empty
);
478 if (item
.Image
is Icon
) {
484 bitmap
= new Bitmap(imageWidth
= this.imageSize
.Width
, imageHeight
= this.imageSize
.Height
, PixelFormat
.Format32bppArgb
);
485 graphics
= Graphics
.FromImage(bitmap
);
486 graphics
.DrawIcon((Icon
)item
.Image
, new Rectangle(0, 0, imageWidth
, imageHeight
));
489 ReduceColorDepth(bitmap
);
490 return list
.Add(bitmap
);
492 else if ((item
.Flags
& ItemFlags
.ImageStrip
) == 0)
493 return list
.Add(CreateImage((Image
)item
.Image
, (item
.Flags
& ItemFlags
.UseTransparentColor
) == 0 ? this.transparentColor
: item
.TransparentColor
));
504 ImageAttributes imageAttributes
;
506 // When ImageSize was changed after adding image strips
507 // Count will return invalid values based on old ImageSize
508 // but when creating handle either ArgumentException will
509 // be thrown or image strip will be added according to the
510 // new ImageSize. This can result in image count
511 // difference that can result in exceptions in methods
512 // that use Count before creating handle. In addition this
513 // can result in the loss of sync with keys. When doing
514 // the same after handle was created there are no problems
515 // as handle will be recreated after changing ImageSize
516 // that results in the loss of images added previously.
518 if ((width
= (image
= (Image
)item
.Image
).Width
) == 0 || (width
% (imageWidth
= this.imageSize
.Width
)) != 0)
519 throw new ArgumentException("Width of image strip must be a positive multiple of ImageSize.Width.", "value");
521 if (image
.Height
!= (imageHeight
= this.imageSize
.Height
))
522 throw new ArgumentException("Height of image strip must be equal to ImageSize.Height.", "value");
524 imageRect
= new Rectangle(0, 0, imageWidth
, imageHeight
);
525 if (this.transparentColor
.A
== 0)
526 imageAttributes
= null;
528 imageAttributes
= new ImageAttributes();
529 imageAttributes
.SetColorKey(this.transparentColor
, this.transparentColor
);
533 for (imageX
= 0; imageX
< width
; imageX
+= imageWidth
) {
534 bitmap
= new Bitmap(imageWidth
, imageHeight
, PixelFormat
.Format32bppArgb
);
535 graphics
= Graphics
.FromImage(bitmap
);
536 graphics
.DrawImage(image
, imageRect
, imageX
, 0, imageWidth
, imageHeight
, GraphicsUnit
.Pixel
, imageAttributes
);
539 ReduceColorDepth(bitmap
);
543 if (imageAttributes
!= null)
544 imageAttributes
.Dispose();
550 private void CreateHandle()
555 if (!this.handleCreated
) {
557 this.list
= new ArrayList(this.count
);
559 this.handleCreated
= true;
561 for (index
= 0; index
< items
.Count
; index
++)
562 AddItemInternal((ImageListItem
)items
[index
]);
566 private Image
CreateImage(Image
value, Color transparentColor
)
572 ImageAttributes imageAttributes
;
574 if (transparentColor
.A
== 0)
575 imageAttributes
= null;
577 imageAttributes
= new ImageAttributes();
578 imageAttributes
.SetColorKey(transparentColor
, transparentColor
);
581 bitmap
= new Bitmap(imageWidth
= this.imageSize
.Width
, imageHeight
= this.imageSize
.Height
, PixelFormat
.Format32bppArgb
);
582 graphics
= Graphics
.FromImage(bitmap
);
583 graphics
.DrawImage(value, new Rectangle(0, 0, imageWidth
, imageHeight
), 0, 0, value.Width
, value.Height
, GraphicsUnit
.Pixel
, imageAttributes
);
586 if (imageAttributes
!= null)
587 imageAttributes
.Dispose();
589 ReduceColorDepth(bitmap
);
593 private void RecreateHandle()
595 if (this.handleCreated
) {
597 this.handleCreated
= true;
598 owner
.OnRecreateHandle();
602 private unsafe void ReduceColorDepth(Bitmap bitmap
)
612 BitmapData bitmapData
;
615 if (this.colorDepth
< ColorDepth
.Depth32Bit
) {
616 bitmapData
= bitmap
.LockBits(new Rectangle(0, 0, bitmap
.Width
, bitmap
.Height
), ImageLockMode
.ReadWrite
, PixelFormat
.Format32bppArgb
);
618 linePtr
= (byte*)bitmapData
.Scan0
;
619 height
= bitmapData
.Height
;
620 widthBytes
= bitmapData
.Width
<< 2;
621 stride
= bitmapData
.Stride
;
623 if (this.colorDepth
< ColorDepth
.Depth16Bit
) {
624 palette
= (this.colorDepth
< ColorDepth
.Depth8Bit
? IndexedColorDepths
.Palette4Bit
: IndexedColorDepths
.Palette8Bit
).Entries
;
626 for (line
= 0; line
< height
; line
++) {
627 lineEndPtr
= linePtr
+ widthBytes
;
628 for (pixelPtr
= linePtr
; pixelPtr
< lineEndPtr
; pixelPtr
+= 4)
629 *(int*)pixelPtr
= ((pixel
= *(int*)pixelPtr
) & AlphaMask
) == 0 ? 0x00000000 : IndexedColorDepths
.GetNearestColor(palette
, pixel
| AlphaMask
);
633 else if (this.colorDepth
< ColorDepth
.Depth24Bit
) {
634 for (line
= 0; line
< height
; line
++) {
635 lineEndPtr
= linePtr
+ widthBytes
;
636 for (pixelPtr
= linePtr
; pixelPtr
< lineEndPtr
; pixelPtr
+= 4)
637 *(int*)pixelPtr
= ((pixel
= *(int*)pixelPtr
) & AlphaMask
) == 0 ? 0x00000000 : (pixel
& 0x00F8F8F8) | AlphaMask
;
642 for (line
= 0; line
< height
; line
++) {
643 lineEndPtr
= linePtr
+ widthBytes
;
644 for (pixelPtr
= linePtr
; pixelPtr
< lineEndPtr
; pixelPtr
+= 4)
645 *(int*)pixelPtr
= ((pixel
= *(int*)pixelPtr
) & AlphaMask
) == 0 ? 0x00000000 : pixel
| AlphaMask
;
651 bitmap
.UnlockBits(bitmapData
);
655 #endregion // ImageCollection Private Instance Methods
657 #region ImageCollection Internal Instance Methods
658 // For use in ImageList
659 internal void DestroyHandle()
661 if (this.handleCreated
) {
662 this.list
= new ArrayList();
664 this.handleCreated
= false;
666 keys
= new ArrayList();
671 // For use in ImageList
672 internal Image
GetImage(int index
)
674 if (index
< 0 || index
>= this.Count
)
675 throw new ArgumentOutOfRangeException("index");
678 return (Image
)list
[index
];
681 // For use in ImageListStreamer
682 internal Image
[] ToArray()
686 // Handle is created even when the list is empty.
688 images
= new Image
[list
.Count
];
692 #endregion // ImageCollection Internal Instance Methods
694 #region ImageCollection Public Instance Methods
695 public void Add(Icon
value)
700 AddItem(new ImageListItem(value));
704 public void Add(Image
value)
709 AddItem(new ImageListItem(value));
713 public int Add(Image
value, Color transparentColor
)
716 return AddItem(null, new ImageListItem(value, transparentColor
));
718 return AddItem(new ImageListItem(value, transparentColor
));
723 public void Add(string key
, Icon icon
)
725 // Argument has name icon but exceptions use name value.
726 AddItem(key
, new ImageListItem(icon
));
729 public void Add(string key
, Image image
)
731 // Argument has name image but exceptions use name value.
732 AddItem(key
, new ImageListItem(image
));
735 public void AddRange(Image
[] images
)
740 throw new ArgumentNullException("images");
742 for (index
= 0; index
< images
.Length
; index
++)
747 public int AddStrip(Image
value)
753 throw new ArgumentNullException("value");
755 if ((width
= value.Width
) == 0 || (width
% (imageWidth
= this.imageSize
.Width
)) != 0)
756 throw new ArgumentException("Width of image strip must be a positive multiple of ImageSize.Width.", "value");
758 if (value.Height
!= this.imageSize
.Height
)
759 throw new ArgumentException("Height of image strip must be equal to ImageSize.Height.", "value");
762 return AddItem(null, new ImageListItem(value, width
/ imageWidth
));
764 return AddItem(new ImageListItem(value, width
/ imageWidth
));
771 if (this.handleCreated
)
779 [EditorBrowsable(EditorBrowsableState
.Never
)]
781 public bool Contains(Image image
)
783 throw new NotSupportedException();
787 public bool ContainsKey(string key
)
789 return IndexOfKey(key
) != -1;
793 public IEnumerator
GetEnumerator()
795 Image
[] images
= new Image
[this.Count
];
798 if (images
.Length
!= 0) {
799 // Handle is created only when there are images.
802 for (index
= 0; index
< images
.Length
; index
++)
803 images
[index
] = (Image
)((Image
)list
[index
]).Clone();
806 return images
.GetEnumerator();
810 [EditorBrowsable(EditorBrowsableState
.Never
)]
812 public int IndexOf(Image image
)
814 throw new NotSupportedException();
818 public int IndexOfKey(string key
)
822 if (key
!= null && key
.Length
!= 0) {
823 // When last IndexOfKey was successful and the same key was
824 // assigned to an image with a lower index than the last
825 // result and the key of the last result equals to key
826 // argument the last result is returned.
828 if (this.lastKeyIndex
>= 0 && this.lastKeyIndex
< this.Count
&& CompareKeys((string)keys
[this.lastKeyIndex
], key
))
829 return this.lastKeyIndex
;
831 // Duplicate keys are allowed and first match is returned.
832 for (index
= 0; index
< this.Count
; index
++)
833 if (CompareKeys((string)keys
[index
], key
))
834 return this.lastKeyIndex
= index
;
837 return this.lastKeyIndex
= -1;
842 [EditorBrowsable(EditorBrowsableState
.Never
)]
844 public void Remove(Image image
)
846 throw new NotSupportedException();
849 public void RemoveAt(int index
)
851 if (index
< 0 || index
>= this.Count
)
852 throw new ArgumentOutOfRangeException("index");
855 list
.RemoveAt(index
);
857 keys
.RemoveAt(index
);
860 Changed (this, EventArgs
.Empty
);
864 public void RemoveByKey(string key
)
868 if ((index
= IndexOfKey(key
)) != -1)
872 public void SetKeyName(int index
, string name
)
874 // Only SetKeyName throws IndexOutOfRangeException.
875 if (index
< 0 || index
>= this.Count
)
876 throw new IndexOutOfRangeException();
881 #endregion // ImageCollection Public Instance Methods
883 #region ImageCollection Interface Properties
884 object IList
.this[int index
] {
890 if (!(value is Image
))
891 throw new ArgumentException("value");
893 this[index
] = (Image
)value;
897 bool IList
.IsFixedSize
{
903 bool ICollection
.IsSynchronized
{
909 object ICollection
.SyncRoot
{
914 #endregion // ImageCollection Interface Properties
916 #region ImageCollection Interface Methods
917 int IList
.Add(object value)
921 if (!(value is Image
))
922 throw new ArgumentException("value");
925 this.Add((Image
)value);
929 bool IList
.Contains(object value)
931 return value is Image
? this.Contains((Image
)value) : false;
934 int IList
.IndexOf(object value)
936 return value is Image
? this.IndexOf((Image
)value) : -1;
939 void IList
.Insert(int index
, object value)
941 throw new NotSupportedException();
944 void IList
.Remove(object value)
947 this.Remove((Image
)value);
950 void ICollection
.CopyTo(Array array
, int index
)
954 for (imageIndex
= 0; imageIndex
< this.Count
; imageIndex
++)
955 array
.SetValue(this[index
], index
++);
957 #endregion // ImageCollection Interface Methods
959 #endregion // Sub-classes
961 #region Public Constructors
964 images
= new ImageCollection(this);
967 public ImageList(System
.ComponentModel
.IContainer container
) : this()
971 #endregion // Public Constructors
973 #region Private Instance Methods
974 private void OnRecreateHandle()
976 EventHandler eh
= (EventHandler
)(Events
[RecreateHandleEvent
]);
978 eh (this, EventArgs
.Empty
);
981 // MS's TypeDescriptor stuff apparently uses
982 // non-public ShouldSerialize* methods, because it
983 // picks up this behavior even though the methods
984 // aren't public. we can't make them private, though,
985 // without adding compiler warnings. so, make then
988 internal bool ShouldSerializeTransparentColor ()
990 return this.TransparentColor
!= Color
.LightGray
;
993 internal bool ShouldSerializeColorDepth()
995 // ColorDepth is serialized in ImageStream when non-empty.
996 // It is serialized even if it has its default value when empty.
1000 internal bool ShouldSerializeImageSize()
1002 // ImageSize is serialized in ImageStream when non-empty.
1003 // It is serialized even if it has its default value when empty.
1005 return images
.Empty
;
1007 return this.ImageSize
!= DefaultImageSize
;
1012 internal void ResetColorDepth ()
1014 this.ColorDepth
= DefaultColorDepth
;
1018 internal void ResetImageSize ()
1020 this.ImageSize
= DefaultImageSize
;
1023 internal void ResetTransparentColor ()
1025 this.TransparentColor
= Color
.LightGray
;
1028 #endregion // Private Instance Methods
1030 #region Public Instance Properties
1032 [DefaultValue(DefaultColorDepth
)]
1034 public ColorDepth ColorDepth
{
1036 return images
.ColorDepth
;
1040 images
.ColorDepth
= value;
1045 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1046 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
1047 public IntPtr Handle
{
1049 return images
.Handle
;
1054 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1055 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
1056 public bool HandleCreated
{
1058 return images
.HandleCreated
;
1062 [DefaultValue(null)]
1063 [MergableProperty(false)]
1064 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
1065 public ImageCollection Images
{
1072 public Size ImageSize
{
1074 return images
.ImageSize
;
1078 images
.ImageSize
= value;
1083 [DefaultValue(null)]
1084 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1085 public ImageListStreamer ImageStream
{
1087 return images
.ImageStream
;
1091 images
.ImageStream
= value;
1097 [DefaultValue(null)]
1098 [Localizable(false)]
1099 [TypeConverter(typeof(StringConverter
))]
1111 public Color TransparentColor
{
1113 return images
.TransparentColor
;
1117 images
.TransparentColor
= value;
1120 #endregion // Public Instance Properties
1122 #region Public Instance Methods
1123 public void Draw(Graphics g
, Point pt
, int index
)
1125 this.Draw(g
, pt
.X
, pt
.Y
, index
);
1128 public void Draw(Graphics g
, int x
, int y
, int index
)
1130 g
.DrawImage(images
.GetImage(index
), x
, y
);
1133 public void Draw(Graphics g
, int x
, int y
, int width
, int height
, int index
)
1135 g
.DrawImage(images
.GetImage(index
), x
, y
, width
, height
);
1138 public override string ToString()
1140 return base.ToString() + " Images.Count: " + images
.Count
.ToString() + ", ImageSize: " + this.ImageSize
.ToString();
1142 #endregion // Public Instance Methods
1144 #region Protected Instance Methods
1145 protected override void Dispose(bool disposing
)
1148 images
.DestroyHandle();
1150 base.Dispose(disposing
);
1152 #endregion // Protected Instance Methods
1155 static object RecreateHandleEvent
= new object ();
1158 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1159 public event EventHandler RecreateHandle
{
1160 add { Events.AddHandler (RecreateHandleEvent, value); }
1161 remove { Events.RemoveHandler (RecreateHandleEvent, value); }
1163 #endregion // Events