简体   繁体   中英

Issue displaying a local image from XAML

I have the below simple xaml:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
  <Grid>
    <Image Source="happyface.jpg"/>
  </Grid>
</Window>

happyface.jpg is included in the project and its Build Action is set to "Content" and Copy To Ouptput Directory is set to "Copy Always".

When looking at the app through the VS designer, everything is ok and I see the image. However, when I run the app, no image is displayed. I see the image is copied to the out out directory. If I put in the entire path as the source (C:\\SANDBOX\\WpfApplication1\\WpfApplication1\\bin\\Debug") it works.

Any ideas as to why the image is not displayed when I run the app? I read about pack URIs but thought that to just simply reference a loose image in the current directory, I can just use the image name.

Thank you.



Edit:

The image to be added is in folder: C:\\WPF in C#\\SANDBOX\\WpfApplication1\\WpfApplication1

The path of the image file in VS: C:\\WPF in C#\\SANDBOX\\WpfApplication1\\WpfApplication1\\happyface.jpg

I created the project through VS, setting the solution directory to "C:\\WPF in C#\\SANDBOX" and left the default project and solution name of WpfApplication1. I also checked the box "Create directory for solution" so I now have the following dir structure:

C:\\WPF in C#\\SANDBOX\\WpfApplication1 - contains the WpfApplication1.sln file

C:\\WPF in C#\\SANDBOX\\WpfApplication1\\WpfApplication1 - contains WpfApplication1.csproj

The jpeg is in the same dir as WpfApplication1.csproj and was added to the project from there. When the solution is built, the output dir is C:\\WPF in C#\\SANDBOX\\WpfApplication1\\WpfApplication1\\bin\\Debug , and the image is copied to that dir.



Edit #2

I tried moving my app to my 32-bit machine and everything works as expected. The image is displayed normally. When I compiled it on my x64, I changed the platform target config in the project to "x86". I am surprised that the issue only occurs when running on a 64-bit machine (XP 64). Any ideas why this might be so?



Edit #3 - I think I found the issue

I enabled tracing to take a closer look at what is going on. Just to make sure I wasn't doing anything crazy, I started over from scratch, not changing anything from the default VS 2008 project that is created for me besides adding the image as content and enabling the tracing.

I complied the app on my x64 machine and ran it. The below is what I got wrt the image control:

System.Windows.Markup Start: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.Markup Stop: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.RoutedEvent Start: 1 : Raise RoutedEvent; RoutedEvent='Image.ImageFailed'; RoutedEvent.HashCode='12289376'; RoutedEvent.Type='System.Windows.RoutedEvent'; Element='System.Windows.Controls.Image'; Element.HashCode='18796293'; Element.Type='System.Windows.Controls.Image'; RoutedEventArgs='System.Windows.ExceptionRoutedEventArgs'; RoutedEventArgs.HashCode='43495525'; RoutedEventArgs.Type='System.Windows.ExceptionRoutedEventArgs'; Handled='False'

System.Windows.RoutedEvent Stop: 1 : Raise RoutedEvent; RoutedEvent='Image.ImageFailed'; RoutedEvent.HashCode='12289376'; RoutedEvent.Type='System.Windows.RoutedEvent'; Element='System.Windows.Controls.Image'; Element.HashCode='18796293'; Element.Type='System.Windows.Controls.Image'; RoutedEventArgs='System.Windows.ExceptionRoutedEventArgs'; RoutedEventArgs.HashCode='43495525'; RoutedEventArgs.Type='System.Windows.ExceptionRoutedEventArgs'; Handled='False'

System.Windows.Markup Start: 16 : Type conversion failed, using fallback; TypeConverter='System.Windows.Media.ImageSourceConverter'; TypeConverter.HashCode='55915408'; TypeConverter.Type='System.Windows.Media.ImageSourceConverter'; String='happyface.jpg'; Value='<null>'

As we can see, the image conversion failed because the Value for the jpg was somehow null.

I copied the app directly to the Desktop folder of my x86 machine and just ran it. Here it worked and we can see the difference in the trace:

System.Windows.Markup Start: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.Markup Stop: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.Markup Start: 15 : Converted value; TypeConverter='System.Windows.Media.ImageSourceConverter'; TypeConverter.HashCode='12289376'; TypeConverter.Type='System.Windows.Media.ImageSourceConverter'; String='happyface.jpg'; Value='pack://application:,,,/ImageContentTest;component/happyface.jpg'; Value.HashCode='43495525'; Value.Type='System.Windows.Media.Imaging.BitmapFrameDecode'

Somehow, on the x86 machine, Value is correctly set to 'pack://application:,,,/ImageContentTest;component/happyface.jpg';

I had the app on my x64 Desktop folder from moving it around earlier and just for kicks ran it from there. To my surprise, it worked! It turns out that the # in the folder path was the culprit. With the # there, it will not work. With the # removed, it works normally. It has nothing to do with x64 vs x86.

I am still not exactly sure why the # would cause such behavior. I would at least expect some type of error to be thrown indicating a bad path or something. In any case, I guess I will be avoiding #'s in paths from now on :)

Thanks to everyone who looked into this with me.

Don't worry about copying it, but set its build action to Resource. You do need to set the URI to the Image to be a valid pack URI. The designer should help you to do this, but if it doesn't it should be in this format:

/[ assembly name ];component[ path within the project ]

For example: /MyAssemblyName;component/Resources/image.png

where the assembly is "MyAssemblyName.dll", and the image is under the Resources directory within the solution.

could you make sure of couple of things please?

the image to be added is in folder "[DIR LOCATION]\\Projects\\WpfApplication1\\Window1" and the path of the image file in VS is "[DIR LOCATION]\\Projects\\WpfApplication1\\Window1\\happyface.jpg

replace [DIR LOCATION] with the correct location.

I created a solution just like you described, and I had no problems either running the solution inside VS or running the *.exe.

One change you could make to try to point you in the right direction is to add a Debug statement to see where the image control thinks the image file is.

I did that by making the following change in the *.xaml file:

        <Image x:Name="displayImage" Source="have_the_dumb.jpg" />

Then, in the *.xaml.cs file, I added a new TraceListener to see what the standalone *.exe says. My constructor looks like this:

    public ImageDisplay()
    {
        Trace.Listeners.Add(new TextWriterTraceListener(@"c:\happyface.trace.log"));
        Trace.AutoFlush = true;

        InitializeComponent();

        Trace.WriteLine(String.Format("Image thinks it's in {0}", displayImage.Source.ToString()));
    }

You may have to add "using System.Diagnostics" for that to work. Then, run your solution & see what the trace file contains. At least you'll know whether the control is looking in the right place for the image.

I think I found the issue

I enabled tracing to take a closer look at what is going on. Just to make sure I wasn't doing anything crazy, I started over from scratch, not changing anything from the default VS 2008 project that is created for me besides adding the image as content and enabling the tracing.

I complied the app on my x64 machine and ran it. The below is what I got wrt the image control:

System.Windows.Markup Start: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.Markup Stop: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.RoutedEvent Start: 1 : Raise RoutedEvent; RoutedEvent='Image.ImageFailed'; RoutedEvent.HashCode='12289376'; RoutedEvent.Type='System.Windows.RoutedEvent'; Element='System.Windows.Controls.Image'; Element.HashCode='18796293'; Element.Type='System.Windows.Controls.Image'; RoutedEventArgs='System.Windows.ExceptionRoutedEventArgs'; RoutedEventArgs.HashCode='43495525'; RoutedEventArgs.Type='System.Windows.ExceptionRoutedEventArgs'; Handled='False'

System.Windows.RoutedEvent Stop: 1 : Raise RoutedEvent; RoutedEvent='Image.ImageFailed'; RoutedEvent.HashCode='12289376'; RoutedEvent.Type='System.Windows.RoutedEvent'; Element='System.Windows.Controls.Image'; Element.HashCode='18796293'; Element.Type='System.Windows.Controls.Image'; RoutedEventArgs='System.Windows.ExceptionRoutedEventArgs'; RoutedEventArgs.HashCode='43495525'; RoutedEventArgs.Type='System.Windows.ExceptionRoutedEventArgs'; Handled='False'

System.Windows.Markup Start: 16 : Type conversion failed, using fallback; TypeConverter='System.Windows.Media.ImageSourceConverter'; TypeConverter.HashCode='55915408'; TypeConverter.Type='System.Windows.Media.ImageSourceConverter'; String='happyface.jpg'; Value='<null>'

As we can see, the image conversion failed because the Value for the jpg was somehow null.

I copied the app directly to the Desktop folder of my x86 machine and just ran it. Here it worked and we can see the difference in the trace:

System.Windows.Markup Start: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.Markup Stop: 13 : Set property value; Object='System.Windows.Controls.Image'; Object.HashCode='18796293'; Object.Type='System.Windows.Controls.Image'; PropertyName='Name'; Value='_imageControl'

System.Windows.Markup Start: 15 : Converted value; TypeConverter='System.Windows.Media.ImageSourceConverter'; TypeConverter.HashCode='12289376'; TypeConverter.Type='System.Windows.Media.ImageSourceConverter'; String='happyface.jpg'; Value='pack://application:,,,/ImageContentTest;component/happyface.jpg'; Value.HashCode='43495525'; Value.Type='System.Windows.Media.Imaging.BitmapFrameDecode'

Somehow, on the x86 machine, Value is correctly set to 'pack://application:,,,/ImageContentTest;component/happyface.jpg';

I had the app on my x64 Desktop folder from moving it around earlier and just for kicks ran it from there. To my surprise, it worked! It turns out that the # in the folder path was the culprit. With the # there, it will not work. With the # removed, it works normally. It has nothing to do with x64 vs x86.

I am still not exactly sure why the # would cause such behavior. I would at least expect some type of error to be thrown indicating a bad path or something. In any case, I guess I will be avoiding #'s in paths from now on :)

Thanks to everyone who looked into this with

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM