DirectoryNotFoundException when creating a BitmapImage - c#

I develop an IOC framework in the form of a DLL that creates the application's main window and displays various WPF Pages in it. There is a folder of PNG images with their Build Action set to Resource. I use code like this to set the sources of WPF Image elements...
MyImage.Source = new BitmapImage(new Uri("/MyAssembly;component/Images/MyImage.png", UriKind.Relative));
This works great. However, there is also a feature where the user can choose to display one of these WPF Pages in a separate window. Here is the mystery: If the user navigates to the page in the main window before showing it in a separate window, all is well. However, if the user shows the page in a separate window before it is shown in the main window, I get a DirectoryNotFoundException saying " Could not find a part of the path 'C:\MyAssembly;component\Images\MyImage.png'."
I discovered the OnLoad cache option and tried the following code...
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri("/MyAssembly;component/Images/MyImage.png", UriKind.Relative);
image.EndInit();
MyImage.Source = image;
However, I then get the DirectoryNotFoundException on the very first image that I attempt to create.
I also tried an absolute URI...
MyImage.Source = new BitmapImage(new Uri("pack://application:,,,/MyAssembly;component/Images/MyImage.png", UriKind.Absolute));
I then get a UriFormatException saying "Invalid URI: Invalid port specified."

I solved the problem by using the 'pack' URI format as shown in the question. However, I needed to make a call to the Application class before I did so. This has the effect of executing the Application's static constructor which registers the 'pack' URI scheme. I found my answer here. The call I used was simply this:
var app = Application.Current;

Related

folder missing in resources

I have the following code for showing an image:
Image im = new Image();
im.Source = new BitmapImage(new Uri("Icons.login.jpg", UriKind.RelativeOrAbsolute));
im.Height = 200;
im.Width = 200;
icons.Add(new IconImagesForDummies() { Name = str, Image = im });
The Image class belongs to System.Windows.Controls.Image. I have added a folder to store images separately from Resources folder (named Icons). But I have set the build action property of all images to Embed Resource and they have been set to Copy Always. I do not know why I can not see the images. I'm using WPF. During debugging I found out that the image path was fine and it founded that, but I do not know the reason, the image was not showed. I have read here but was useless.
Is there something wrong with the Uri?
EDIT: maybe its just this simple
im.Source = new BitmapImage(new Uri(#"Icons\login.jpg", UriKind.Relative));
Edit: changing build action to content works.

WPF cannot implicitly convert system.drawing.bitmap to media.brush

I want to change the background of a button manually in my WPF app.
I have an image imported into my resources and I want to do:
MyButton.Background = MyProject.Properties.Resources.myImage;
But I get the error:
cannot implicitly convert system.drawing.bitmap to media.brush
How can I do this??
You should read about brushes first here.
And then use ImageBrush, something like this:
MyButton.Background = new ImageBrush(...);
(or, maybe, put the brush into resources...)
UPDATE
You can find how to create imageSource from bitmap easilly. for example, here. Like:
var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(MyProject.Properties.Resources.myImage.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
MyButton.Background = new ImageBrush(bitmapSource);
In a WPF application, you do usually not add image resources as you did in WinForms.
Instead you add the image file directly to your Visual Studio project, just like any other file. If there are multiple images, it may make sense to put them in a subfolder of the project (e.g. called "images"). The Build Action of that file has to be set to Resource (which is the default for image files).
Now you can create a BitmapImage from a Pack URI to that file.
Finally you create an ImageBrush from the BitmapImage to set the Background property.
var uri = new Uri("pack://application:,,,/images/myImage.jpg");
var image = new BitmapImage(uri);
MyButton.Background = new ImageBrush(image);

Access images in Windows Phone Class Library

I want to access some images in my Windows Phone class library, but how can I access these images?
I have a method which will set the image, but
new Uri("/Assets/Images/MyImage.png", UriKind.Relative);
doesn't work. I've tried setting the image to Resource instead of Content, but it also doesn't work.
So how can I provice images in my class library?
From what I gather it looks like you are trying to set the source of an image from the XAML code behind file.
If so you can do so as follows:
MyImage.Source = new BitmapImage(new Uri("/Assets/Images/MyImage.png", UriKind.Relative));
Hope this helps.

Image.Source (with binding) is blocking image file after binding is removed

In a GridView, I've templated the items so an Image control inside that template receives an Uri using a binding (also tried with BitmapImage) to show a picture file. It works, but I cannot delete those files because those files are blocked. Even if I clear the collection feeding the GridView.ItemsSource, and even if I call GC.Collect(), they are still blocked.
Thanks to Philip for his working suggestion... as I used a Converter to feed a BitmapImage to every Image control, found some particular things had to do to make it work, and here it is for future reference:
InMemoryRandomAccessStream Ras = new InMemoryRandomAccessStream();
var archivo = CartoonsDownloader.FolderImagenes.GetFileAsync(TheFileName);
var fileStream = CartoonsDownloader.FolderImagenes.OpenStreamForReadAsync(TheFileName);
fileStream.Result.CopyTo(Ras.AsStreamForWrite());
BitmapImage MapaDeBits = new BitmapImage();
// Even it's RANDOM, I have to manually "Seek" it at 0.
Ras.Seek(0);
MapaDeBits.SetSource(Ras);
MapaDeBits.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
return MapaDeBits;
This could be a bug in the XAML stack (so you could report it on MSDN forums), or just a side effect of its nature of caching images. As an alternative - you can open the file yourself and set the image using the SetSource method. Then you should have better control over the file access.

How to set the Icon property in code? How to understand the way it is done in XAML?

When I choose an Icon for a wpf Window through the designer I get the following XAML:
<Window Icon="/MyNameSpace;component/myIcon.ico">
Please explain this notation for me!
Say I want to set the Icon in the code behind. How do I translate the XAML to C#?
After much trial and error I found the code below to work, admittedly without comprehending it fully:
var window=new Window();
var uri=new Uri("pack://application:,,,/MyAssembly;component/Icon.ico",
UriKind.RelativeOrAbsolute));
// var uri=new Uri("icon.ico",UriKind.Relative) works just as well
window.Icon = BitmapFrame.Create(uri);
This is the "pack URI scheme". You can find more about it on MSDN: http://msdn.microsoft.com/en-us/library/aa970069.aspx
In code-behind, you could write the following :
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri("pack://application:,,,/MyNamespace;component/myIcon.ico");
bitmap.EndInit();
this.Icon = bitmap;
Note that the "MyNamespace" part isn't actually the namespace (since a ressource is not code, it doesn't have a namespace), but the assembly name.

Categories