BaseGallery.GetThumbnailImage Event

Occurs each time the gallery needs to display an item whose image is loaded asynchronously.

Namespace: DevExpress.XtraBars.Ribbon.Gallery

Assembly: DevExpress.XtraBars.v20.1.dll

Declaration

[DXCategory("Image")]
public event GalleryThumbnailImageEventHandler GetThumbnailImage
<DXCategory("Image")>
Public Event GetThumbnailImage As GalleryThumbnailImageEventHandler

Event Data

The GetThumbnailImage event's data class is GalleryThumbnailImageEventArgs. The following properties provide information specific to this event:

Property Description
DataSourceIndex Gets the index of the currently processed item among other items in the source (the item's index in the bound data source for data-aware controls, e.g., GridControl). Inherited from ThumbnailImageEventArgs.
DesiredThumbnailSize Stores the desired size of thumbnail images, generated using the ThumbnailImageEventArgs.CreateThumbnailImage method. Inherited from ThumbnailImageEventArgs.
Item Gets the currently processed item.
ThumbnailImage Gets or sets the image that will be assigned to an item that fired this event. Inherited from ThumbnailImageEventArgs.

Remarks

The GetThumbnailImage event allows you to assign thumbnail images for gallery items that use the asynchronous image loading feature. See the example below to learn more.

Example

This example illustrates how to load BaseGallery item images asynchronously. This loading mode is useful when you have a lot of gallery items and/or their images are very large, which can cause performance issues on the application start-up. In this example, the GalleryControl with the attached GalleryControlGallery is used.

IMPORTANT

Asynchronously loaded images can be retrieved from any source. This particular example uses the DataSet object that loads data from the DimProducts table of the Microsoft's sample Adventure Works database. For this lesson, you will only need two columns from this table - EnglishProductName and LargePhoto. Refer to MSDN if you experience problems adding this data source to your application.

  1. Drop a GalleryControl onto the form and, using its smart tag, create a new group that will contain our items.
  2. Populate the gallery group with GalleryItems. Again, the way you do it is irrelevant. For example, the code below generates a blank item for each data source record and assigns the EnglishProductName column's value to this item.

    
    private void createItems() {
        dimProductTableAdapter1.Fill(this.adventureWorksDW2008R2DataSet.DimProduct);
        for (int row = 0; row < adventureWorksDW2008R2DataSet.DimProduct.Count; row++) {
            string itemName = adventureWorksDW2008R2DataSet.DimProduct.Rows[row][adventureWorksDW2008R2DataSet.DimProduct.EnglishProductNameColumn].ToString();
            galleryControl1.Gallery.Groups[0].Items.Add(new DevExpress.XtraBars.Ribbon.GalleryItem(null, itemName, null));
        }
    }
    
  3. To enable loading gallery item images asynchronously, access the BaseGallery.OptionsImageLoad properties section and set the GalleryOptionsImageLoad.AsyncLoad property to true. You can also set the desired animation type and enable or disable the random image loading order. The GalleryOptionsImageLoad.DesiredThumbnailSize property sets the size of an image that will be created from the data source data. This thumbnail image will be later resized according to the BaseGallery.ItemImageLayout property to fit the image size specified by the BaseGallery.ImageSize property.

    
    private void setGalleryOptions() {
        //Base gallery options
        galleryControl1.Gallery.ShowItemText = true;
        galleryControl1.Gallery.ImageSize = new Size(256, 256);
        galleryControl1.Gallery.ItemCheckMode = DevExpress.XtraBars.Ribbon.Gallery.ItemCheckMode.Multiple;
        galleryControl1.Gallery.ItemImageLayout = DevExpress.Utils.Drawing.ImageLayoutMode.ZoomInside;
        //Image load options
        galleryControl1.Gallery.OptionsImageLoad.AsyncLoad = true;
        galleryControl1.Gallery.OptionsImageLoad.AnimationType = DevExpress.Utils.ImageContentAnimationType.SegmentedFade;
        galleryControl1.Gallery.OptionsImageLoad.DesiredThumbnailSize = new Size(1024, 1024);
    }
    
  4. Your application will now raise the BaseGallery.GetThumbnailImage event each time it needs to display an item with no image. Handle this event to call the e.CreateThumbnailImage method. This method will receive an image loaded from the data source LargePhoto column and create a thumbnail image of the specific size set in the previous step. To get the item index (and thus the index of the data source row related to this item), read the e.DataSourceIndex property. Finally, assign the image returned by the CreateThumbnailImage method to the e.ThumbnailImage property.

    
    private void galleryControlGallery1_GetThumbnailImage(object sender, DevExpress.Utils.ThumbnailImageEventArgs e) {
        using(var memStream = new MemoryStream(adventureWorksDW2008R2DataSet.DimProduct.Rows[e.DataSourceIndex][adventureWorksDW2008R2DataSet.DimProduct.LargePhotoColumn] as byte[])) {
            Image thumbImg = Image.FromStream(memStream);
            e.ThumbnailImage = e.CreateThumbnailImage(thumbImg);
        }
    }
    
  5. Optionally, handle the BaseGallery.GetLoadingImage event to pass your custom loading indicator to the e.LoadingImage property. This indicator will be shown each time the gallery item is already visible but its image is still being loaded.

The following animation illustrates the runtime result. You can see the images being loaded after gallery items and the animation effect following this process.

BaseGallery - Async Image Load Example

The complete code is listed below.

namespace GalleryAsyncLoad {
    public partial class Form1 : XtraForm {
        public Form1() {
            InitializeComponent();
            setGalleryOptions();
            createItems();
        }

        private void Form1_Load(object sender, EventArgs e) {
            this.dimProductTableAdapter1.Fill(this.adventureWorksDW2008R2DataSet.DimProduct);
        }

        private void galleryControlGallery1_GetThumbnailImage(object sender, DevExpress.Utils.ThumbnailImageEventArgs e) {
            using(var memStream = new MemoryStream(adventureWorksDW2008R2DataSet.DimProduct.Rows[e.DataSourceIndex][adventureWorksDW2008R2DataSet.DimProduct.LargePhotoColumn] as byte[])) {
                Image thumbImg = Image.FromStream(memStream);
                e.ThumbnailImage = e.CreateThumbnailImage(thumbImg);
            }
        }

        private void setGalleryOptions() {
            //Base gallery options
            galleryControl1.Gallery.ShowItemText = true;
            galleryControl1.Gallery.ImageSize = new Size(256, 256);
            galleryControl1.Gallery.ItemCheckMode = DevExpress.XtraBars.Ribbon.Gallery.ItemCheckMode.Multiple;
            galleryControl1.Gallery.ItemImageLayout = DevExpress.Utils.Drawing.ImageLayoutMode.ZoomInside;
            //Image load options
            galleryControl1.Gallery.OptionsImageLoad.AsyncLoad = true;
            galleryControl1.Gallery.OptionsImageLoad.AnimationType = DevExpress.Utils.ImageContentAnimationType.SegmentedFade;
            galleryControl1.Gallery.OptionsImageLoad.DesiredThumbnailSize = new Size(1024, 1024);
        }

        //Populate the gallery with items
        private void createItems() {
            dimProductTableAdapter1.Fill(this.adventureWorksDW2008R2DataSet.DimProduct);
            for (int row = 0; row < adventureWorksDW2008R2DataSet.DimProduct.Count; row++) {
                string itemName = adventureWorksDW2008R2DataSet.DimProduct.Rows[row][adventureWorksDW2008R2DataSet.DimProduct.EnglishProductNameColumn].ToString();
                galleryControl1.Gallery.Groups[0].Items.Add(new DevExpress.XtraBars.Ribbon.GalleryItem(null, itemName, null));
            }
        }
    }
}
See Also