Skip to main content
.NET 8.0+

ImageLoader.CustomGetImageInfo Event

Occurs before image metadata is loaded.

Namespace: DevExpress.ExpressApp.Utils

Assembly: DevExpress.ExpressApp.v24.2.dll

NuGet Package: DevExpress.ExpressApp

Declaration

public static event EventHandler<CustomGetImageInfoEventArgs> CustomGetImageInfo

Event Data

The CustomGetImageInfo event's data class is DevExpress.ExpressApp.Utils.CustomGetImageInfoEventArgs.

Remarks

Handle this event to manually provide an ImageInfo object via the CustomizeImageInfoEventArgs.ImageName parameter. The example below demonstrates how to load images from a database.

  • Implement the following MyImageObject business class:

    using DevExpress.Persistent.Base;
    using DevExpress.Persistent.BaseImpl.EF;
    // ...
    [DefaultClassOptions]
    public class MyImageObject : BaseObject {
        public virtual string Name { get; set; }
        [ImageEditorAttribute(ImageEditorMode.PictureEdit, ImageEditorMode.PictureEdit, 
            DetailViewImageEditorFixedHeight = 32, DetailViewImageEditorFixedWidth = 32)]
        [VisibleInListView(true)]
        public virtual byte[] Image { get; set; }
    }
    
    // Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.
    
  • Create several predefined MyImageObject instances on the overridden ModuleUpdater.UpdateDatabaseAfterUpdateSchema method.

    public override void UpdateDatabaseAfterUpdateSchema() {
        base.UpdateDatabaseAfterUpdateSchema();
        MyImageObject image1 = ObjectSpace.CreateObject<MyImageObject>();
        image1.Name = "Image 1";
        var stream = new System.IO.MemoryStream();
        ImageLoader.Instance.GetSmallImageInfo("Action_Save").Image.Save(stream, ImageFormat.Png);
        image1.Image = stream.ToArray();
    
        MyImageObject image2 = ObjectSpace.CreateObject<MyImageObject>();
        image2.Name = "Image 2";
        stream = new System.IO.MemoryStream();
        ImageLoader.Instance.GetSmallImageInfo("Action_Delete").Image.Save(stream, ImageFormat.Png);
        image2.Image = stream.ToArray();
        ObjectSpace.CommitChanges();
     }
    
  • In the WinForms application project, edit the Program.cs (Program.vb) file and handle the static CustomGetImageInfo event before the XafApplication.Setup method is called.

    using System.IO;
    using System.Drawing;
    using System.Drawing.Imaging;
    // ...
    ImageLoader.CustomGetImageInfo += (sender, e) => {
        if(e.ImageName.StartsWith(MyWindowController.MyImagePrefix)) {
            int key;
            string key_string = e.ImageName.Split('_')[1];
            if(int.TryParse(key_string, out key)) {
                using(IObjectSpace objectSpace = winApplication.CreateObjectSpace(typeof(MyImageObject))) {
                    MyImageObject imageObject = objectSpace.GetObjectByKey<MyImageObject>(key);
                    if(imageObject != null) {
                        e.ImageInfo = new ImageInfo(e.ImageName, Image.FromStream(new MemoryStream(imageObject.Image)), null);
                        e.Handled = true;
                    }
                }
            }
        }
    };
    
  • Handle the static CustomGetImageInfo event in the Application_Start method located in the Global.asax.cs (Global.asax.vb) file. In contrast to the WinForms application, pass an URL that will be included into the page markup as the imageUrl parameter of the ImageInfo constructor. The browser will query the content by this URL in a separate request that will be processed by the BinaryDataHttpHandler.

    using System.IO;
    using System.Drawing;
    using System.Drawing.Imaging;
    using DevExpress.ExpressApp.Web.Editors.ASPx;
    // ...
    ImageLoader.CustomGetImageInfo += (s, args) => {
        if (args.ImageName.StartsWith(MyWindowController.MyImagePrefix)) {
            int key;
            string key_string = args.ImageName.Split('_')[1];
            if (int.TryParse(key_string, out key)) {
                using (IObjectSpace objectSpace = WebApplication.Instance.CreateObjectSpace(typeof(MyImageObject))) {
                    MyImageObject imageObject = objectSpace.GetObjectByKey<MyImageObject>(key);
                    if (imageObject != null) {
                        args.ImageInfo = new ImageInfo(
                                args.ImageName, Image.FromStream(new MemoryStream(imageObject.Image)),
                                ImageProcessorsHelper.GetImageUrl(objectSpace, imageObject, "Image"));
                        args.Handled = true;
                    }
                }
            }
        }
    };
    
  • Now, you can specify images as follows:

    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.Actions;
    // ...
    public class MyWindowController : WindowController {
        public const string MyImagePrefix = "MyImageObject_";
        SingleChoiceAction action;
        public MyWindowController() : base() {
            this.TargetWindowType = WindowType.Main;
            action = new SingleChoiceAction(this, "My Action", DevExpress.Persistent.Base.PredefinedCategory.Edit);
            action.ImageMode = ImageMode.UseItemImage;
            action.ItemType = SingleChoiceActionItemType.ItemIsOperation;
        }
        protected override void OnActivated() {
            base.OnActivated();
            action.Items.Clear();
            using(IObjectSpace objectSpace = Application.CreateObjectSpace(typeof(MyImageObject))) {
                foreach(MyImageObject imageObject in objectSpace.GetObjects<MyImageObject>()) {
                    ChoiceActionItem item = new ChoiceActionItem();
                    item.Caption = imageObject.Name;
                    item.ImageName = MyImagePrefix + imageObject.ID;
                    action.Items.Add(item);
                }
            }
        }
    }
    
See Also