ImageLoader.CustomGetImageInfo Event

Occurs before image metadata is loaded.

Namespace: DevExpress.ExpressApp.Utils

Assembly: DevExpress.ExpressApp.v18.2.dll

Declaration

public static event EventHandler<CustomGetImageInfoEventArgs> CustomGetImageInfo
Public Shared Event CustomGetImageInfo As EventHandler(Of CustomGetImageInfoEventArgs)

Event Data

The CustomGetImageInfo event handler receives an argument of the DevExpress.ExpressApp.Utils.CustomGetImageInfoEventArgs type.

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.Xpo;
    // ...
    [DefaultClassOptions]
    public class MyImageObject : XPObject {
        public MyImageObject(Session session) : base(session) { }
        public string Name { get; set; }
        [ImageEditorAttribute(ImageEditorMode.PictureEdit, ImageEditorMode.PictureEdit, 
            DetailViewImageEditorFixedHeight = 32, DetailViewImageEditorFixedWidth = 32)]
        [VisibleInListView(true), Size(SizeAttribute.Unlimited)]
        public byte[] Image { get; set; }
    }
    
  • 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;
                    }
                }
            }
        }
    };
    
  • In the Global.asax.cs (Global.asax.vb) file, handle the static CustomGetImageInfo event before the XafApplication.Setup method is called. 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.Oid;
                    action.Items.Add(item);
                }
            }
        }
    }
    
See Also