|
-
May 2nd, 2011, 03:03 PM
#1
[WPF] Images not loading correctly
Hi,
I am writing a simple contact manager application to learn WPF and I've run into a strange problem. I am guessing the problem is WPF-related (I don't see anything wrong with my logic) but I could be wrong of course...
I am trying to include the option of storing an image with each contact. The contacts are stored in a database, but I chose the store the images outside of the database because the database would otherwise blow up really fast. Now I am simply saving the images in the Application Data folder for my application. The images are named after the ID of the corresponding contact, prefixed with a 'c' (for contact, there's also 'g' for group, etc). So a contact with ID 14 will should have a corresponding image in '..../Users/AppData/Local/ContactManager/Images/c14.png'
This way I don't have to store the path of the image in the database (it will always be the same for each contact anyway).
Anyway, what I'm doing is this:
1. After the contact details are loaded from the database, I check if its image exists, and if it does I create a new BitmapImage from the source:
csharp Code:
public partial class ContactManager { partial void AfterLoad(Contact contact) { var imagePath = GetImagePath(contact); if (File.Exists(imagePath)) { contact.Image = LoadImage(imagePath); } } public static BitmapImage LoadImage(string path) { var image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.UriSource = new Uri(path); image.EndInit(); return image; } }
(GetImagePath returns the correct path, verified)
I am specifying the CacheOption as OnLoad so that it doesn't lock the file, since I need to delete it later.
2. After the contact details have been saved to the database again (during this time, the user could have changed the Image property of the contact), I first delete the existing image (if it exists), and if the Image property is not null I save the new image to the AppData location. The deleting is done so that no images remain after a contact has its image deleted (or the contact is deleted). This is the reason I had to use CacheOption = OnLoad, otherwise the file delete is blocked.
csharp Code:
partial void AfterInsert(Contact contact) { SaveImage(contact); } partial void AfterUpdate(Contact contact) { SaveImage(contact); } private static void SaveImage(Contact contact) { var imagePath = GetImagePath(contact); if (File.Exists(imagePath)) { File.Delete(imagePath); } if (contact.Image == null) return; CreateImageFile(contact, imagePath); } public static string CreateImageFile(Contact contact, string path = null) { var filePath = path ?? GetImagePath(contact); if (contact.Image != null) { var encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(contact.Image)); using (var filestream = new FileStream(filePath, FileMode.Create)) { encoder.Save(filestream); } } return filePath; }
I don't see anything wrong with this logic, although I might be wrong of course.
Anyway, the problem is this: when I edit a Contact and change its image, the old image is displayed in my program, even though the image in the AppData folder is the new image.
When editing a Contact, I show a window where the user can click the picture and choose a new image via an OpenFileDialog:
csharp Code:
public void SelectImageCommandExecute() { var dialog = new OpenFileDialog(); dialog.Multiselect = false; dialog.Filter = "Image Files|*.bmp;*.jpg;*.jpeg;*.gif;*.png|All Files|*.*"; if (dialog.ShowDialog().GetValueOrDefault()) { var image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.UriSource = new Uri(dialog.FileName); image.EndInit(); this.Contact.Image = image; } }
When the user does this, the picture in the window changes immediately (as well as the image in the list of contacts) because it is databound to the Image property. Then the user clicks OK after which the contact is saved to the database and the AfterUpdate method from above is called. The old image is deleted successfully (checked by debugging), and the new image is created successfully as well.
When the 'edit contact' window is closed, the list of contacts is updated by loading them from the database again. This is where it goes wrong: after this is done, the contact has the old image again!
I think this is really strange because it is loading its image via the LoadImage method above, which simply gets the desired path (which is correct and contains the new image) and creates an image from that. For some reason, the image it creates from that is the old image, not the new image.
What's going on? Is there some kind of image caching I don't know about? It seems to me that the LoadImage method is still loading the old image in some weird way even though I clearly tell it to load the image from a specific path, which contains the new image...
Edit:
Let me back this up with some 'evidence'.
I put a breakpoint in the LoadImage method. You can see from which path it is loading the image, and you can see that file in the explorer window, which is clearly some yellow tulips:
http://i51.tinypic.com/15nk8ew.png
I continue running, the Image property of the contact is set to the image returned by LoadImage, and the result is... not yellow tulips...?
http://i51.tinypic.com/k20kdj.png
Help??
Last edited by NickThissen; May 2nd, 2011 at 03:15 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|