Using Custom Images
This article highlights how to incorporate custom images throughout the application for your own brand/theme without having to rely on the system provided ones. It covers the following major points:
- Including custom images as part of your solution
- Automatically upgrading any database to include your custom image
- Referring to, and using, your custom image everywhere throughout the application
Tip
This article assumes you are familiar with the following LemonEdge concepts:
- Creating An AddIn: How to create a .net dll referencing the LemonEdge dlls.
- DesigningEntities: How to create entities in the platform that we can then provide default images for
Note
You can follow along with this article by downloading the API Examples projects which provide the code examples discussed here.
Image Concepts
Custom images in the LemonEdge platform allow you to upload any image that can then be used throughout the application in place of any image in the system. See here for more information on creating and using custom images through the LemonEdge application itself.
Custom images can be used throughout the application in the following places:
- All Commands either view commands, main menu commands, or commands directly on views.
- The icon for a view
- The default icon for an entity when opened in a tab
- As an image in the image view
Whenever an image is displayed in the application, you will always have the ability to customise that image to use a different system one or any of the custom images you have uploaded into the system.
Creating A Custom Image
you can always just upload custom images through the system Custom Images functionality, and refer to those images anywhere in the application. However you can also include custom images as part of you AddIn dll and ensure they automatically create those custom images for you in the database whenever a system upgrade takes place.
Caution
As these images can be used anywhere in the application, it is best to use a png format with transparency set for unwanted background space. This way the image should still look correct at different sizes and with different themes in place depending on the context the image is placed in.
Adding The Image To Your AddIn
To create an image the first thing you need to do is add it to your core assembly (as we want it to take part in the upgrade process which only happens with AddIns marked as core dlls).
You can do that by following these simple steps:
- Create a folder in your project named Images
- Add your png, or other image type, files into the folder
- Set their 'Build Action' to 'Embedded Resource'
Important
All Custom Images are uniquely referenced throughout the system using a unique ImageID. Just like with designing entities you need to create a unique id for each image, which can be done using any method you prefer, like so:
- CSharp:
Guid.NewGuid()
- SQL:
select NEWID()
- Online: Click here for generator
- etc...
Once you have a unique id for each image you've added to your dll, we recommend creating an enum and helper class for referencing your images like so:
public enum MyAppImage : short
{
Image1,
Image2
}
public static class ImageHelper
{
public static Guid GetUniqueID(this MyAppImage type) =>
type switch
{
MyAppImage.Image1 => Image1ID,
MyAppImage.Image2 => Image2ID
_ => throw new ArgumentOutOfRangeException(nameof(type))
};
public const string Image1 = "624bb7d1-1627-4fe7-baf2-9d83e0397665";
public static Guid Image1ID => new Guid(Image1);
public const string Image2 = "f76e1e5f-5916-4d51-931a-fe649509cdec";
public static Guid Image2ID => new Guid(Image2);
}
This way you can easily refer to the image id throughout the API using the following:
MyAppImage.Image1.GetUniqueID();
Including The Image In The Database Upgrade
Now you have the images, and their associated global unique ids, in your project, we simply need to ensure that we create, or update, Custom Image records for each of them during the upgrade. We can do that using the following interface implementation:
public class CustomImageUpdater : IDefaultMenuInserter
{
public async Task UpdateDefaultMenus(IDefaultMenuItemCreator menuCreator)
{
foreach(var img in LemonEdge.Utils.EnumHelper.GetValues<MyAppImage>())
await menuCreator.EnsureImageExists(img.ToString(), img.GetUniqueID(), $"MyApp.Images.{img.ToString()}.png", System.Reflection.Assembly.GetExecutingAssembly());
}
}
Caution
This assumes the enum MyAppImage has the same name for each value as the actual file names of the images you've added to the project. You can of course add each file individually instead without enumerating an enum, and can even use the EnsureImageExists overload which takes an array of bytes for the image instead of an embedded image resource name from the assembly.
There are many ways to integrate with the LemonEdge upgrade process including taking complete custom control issuing sql commands if you want (See Custom Upgrades for more information). Implementing the IDefaultMenuInserter interface is a quick and easy way to integrate menu changes and image changes into the upgrade process and the resetting of system roles.
Note
There is only one method to implement, the UpdateDefaultMenus method which provides a IDefaultMenuItemCreator implementation to help easily upgrade the menu for any role, and system custom images.
We use that interface in this example to simply ensure all our custom images exist.
Using The Custom Image:
To reference an image throughout the application using the API you can just pass in your unique image id.
Important
Wherever the application uses an image in the API it will have an overload that takes the ImageType enum which references system images, or a Guid (or string representation of a guid for constants in attributes) which is a unique global reference to a Custom Image unique ImageID.
For instance to provide the default icon the system should use when opening an entity you can use the following attribute when designing an entity:
///Attributes.EntityDefinition Attribute here ...
[Attributes.DefaultEntityIcon(ImageHelper.Image1)]
public interface IMyAppEntity : LemonEdge.API.Core.IBaseEntityWithPermissions,
{
///My App Entity property definitions here
}
See Designing Entities for more information on creating entities using code. Adding the Default Entity Icon attribute to your entity (as shown here) will ensure whenever a tab is opened to view your entity it will have the specified image as the default icon.