Reputation: 33
I am trying to dynamically populate a Menu in code and set its icon in c#.
I have read this post here and the answer given seems perfectly reasonable:
WPF setting a MenuItem.Icon in code
My interpretation:
mItem.Icon = new Image
{
//filename is just image.png in build output folder
Source = new BitmapImage(new Uri(fileName, UriKind.Relative))
};
but when it comes to run-time, the icons aren't there. Upon inspecting the data in the WPF visualiser, it says the ActualHeight and ActualWidth of the image are 0 and it doesn't look initialised (thas's to say, IsInitialized and IsLoaded are false).
I'd wager that I'm making some kind of rookie mistake somewhere but I'm just not seeing it (for the record, every other aspect of the menu is working as expected)
Thanks in advance :)
Edit 1: At the moment, the image is just a placeholder for testing which I have added as a link to the project then set the 'build action' to 'none' and the 'copy to output directory' to 'copy if newer'. The image is called "buttonIndicator_off.png" and the filename string at runtime is "buttonIndicator_off.png"
Edit 2: also tried this:
var bm = new BitmapImage();
bm.BeginInit();
bm.CacheOption = BitmapCacheOption.OnLoad;
bm.UriSource = new Uri(fileName, UriKind.Relative);
bm.EndInit();
mItem.Icon = new Image {
Source = bm
};
and setting the images to compile as a resource and using:
mItem.Icon = new Image
{
Source = new BitmapImage( new Uri("pack://application:,,,/buttonIndicator_off.png"))
};
I'm almost certain all these solutions should work so I'm starting to think something odd is happening.
Edit 3: tested image with a rectangle fill:
rectangle_testImage.Fill = new ImageBrush(bm);
and this works
Upvotes: 2
Views: 2033
Reputation: 63317
After some attempts, I've successfully made it work. The problem is you have to set the CacheOption
to BitmapCacheOption.OnLoad
. The important thing is we have to place all the initializing code in between the BeginInit()
and EndInit()
calls:
var bm = new BitmapImage();
bm.BeginInit();
bm.CacheOption = BitmapCacheOption.OnLoad;
bm.UriSource = new Uri(fileName, UriKind.Relative);
bm.EndInit();
mItem.Icon = new Image {
Source = bm
};
A special thing is if you try setting some Background
to some ImageBrush
initializing from your BitmapImage
, we don't need any steps above. (Just using one constructor call with the Uri passed in).
Also when embedding your image as a Resource
(instead of None
), you can try this code instead:
mItem.Icon = new Image {
Source = new BitmapImage(
new Uri("pack://application:,,,/buttonIndicator_off.png"))
};
Upvotes: 1