I have a custom control with property of type Uri. When I set this Uri to a relative path "InterfaceImages/Wait.gif", I would expect it to translate into the current directory when I use it to open that file. The expected directory would look something like this:
C:\Users\MyUsername\Documents\Visual Studio 2012\Projects\MySolution\MyProject\InterfaceGraphics\Wait.gif
but instead, WPF mangles it into this:
//-->Note the lowercased filenames<--//
C:\Users\MyUsername\documents\visual studio 2012\Projects\MySolution\MyProject\bin\Debug\InterfaceGraphics\Wait.gif
causing the application to throw an exception: "Could not find a part of the path '[path-shown-above]'."
NOWHERE in my code do I mess with the current directory. So why is it doing this?
I don't know how relevant this is, but the function call that throws it is:
_gifDecoder = new GifBitmapDecoder(this.GifSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
where this.GifSource is a property of type System.Uri, and the XAML that creates the item and sets the property looks like this:
<local:GifImage x:Name="WaitIcon" HorizontalAlignment="Center"
Height="100" VerticalAlignment="Center" Width="100"
MaxWidth="100" MaxHeight="100"
GifSource="InterfaceGraphics/Wait.gif"/>
By default, the working directory is the one containing the executable. The executable generated by Visual Studio is in the bin/Debug (or bin/Release) subfolder of your project, so that's your working directory. Since the absolute path is the combination of the working directory and the relative path, what you're seeing is perfectly normal.
You have several options:
set the "copy to output directory" property to true on the project items that you want available in the executable's directory
change the working directory in the project's debug properties to be the project directory, rather than the output directory
embed the images in your app as resources (you will need to change the code accordingly to load the images)
BTW, if you want to display animated GIF images, you can use my WpfAnimatedGif library, which does exactly that. It is also available as a NuGet package.
Related
So I'm trying to set a custom image for a form application I've made. The images I'm trying to target are in a folder called "Images" on the same level as my Solution file. The solution file is a C# windows forms (net core framework) solution. It's a basic form app that I want to display an image based on a users selection, however right now I get an unhandled exception everytime I try to set the image with this code:
picFood.Image = Image.FromFile("../../Images/burger.jpg");
The exact error is "System.IO.FileNotFoundException: ../../Images/burger.jpg"
In another totally unrelated solution this works. Folder structure is the same. A folder called Images, on the same directory level as the .sln file holds the images there. They're in my solution explorer and everything. I've tried this with one "../" and no "../" as well so I'm not sure what to do from here.
Files with relative paths are opened relative to the working directory of your application.
In this case, when launching from within Visual Studio, the default is the bin folder where the compiled application is put by default.
So if your binary is in <project dir>/bin/Debug/App.exe this path will resolve to <project dir>/Image/burger.jpg.
If you have changed something in your build configuration, or your application switches directory at runtime (e.g. via Directory.SetCurrentDirectory), this path may be different than you expect.
To understand your issue, I suggest you start looking at what your working directory is. You can obtain that in your code via Directory.GetCurrentDirectory().
You can also resolve your relative path using Path.GetFullPath.
Print these two values to see where your program attempts to load the file from.
Keep in mind that any image files you put in the solution/project folder will need to be copied with your binary if you want to use them.
To use relative paths without .. you can copy them alongside your binary during compilation, see:
VS2010 How to include files in project, to copy them to build output directory automatically during build or publish and Copying Visual Studio project file(s) to output directory during build for how to do that.
I need to make a game for school.
I was adding some sound effects and music.
I have the paths to the .wav in the class and it will play them, but only when I start the game from the bin map in the project. I figgered out that the files are not included inside off the build. I started looking for it but could not find the correct way for it.
I have:
MediaPlayer _musicPlayer = new MediaPlayer();
string s = System.IO.Packaging.PackUriHelper.UriSchemePack;
Uri uri = new Uri(#"pack://application:,,,/{Assembly name};component/Resources/Sounds/Music/Main_theme_-_Thiago_Adamo.wav")
_musicPlayer.Open(uri);
_musicPlayer.Play();
This however does not work. If I add an messagebox with:
uri.IsFile.ToString()
It displays false.
On the file I set the propeties to be:
Build Action: Resource
Copy To Output Directory: Copy Always
I hope someone can help me.
Add the files to the project in your solution in Visual Studio, so they show up in the Solution Explorer (docked on the right side of the VS window by default). Click on a file so you see the properties window for that file (shown below the Solution Explorer in VS by default). Make sure the Copy to Output Directory property is set to either Copy Always or Copy if newer, and the Build Action is set to Content. Do this for each sound file you need.
At this point, the files will be copied to same folder as your application when you build it. They will not be packaged. They'll just be there in the file system next to your program. If you build the application in Debug mode, this is in the /bin/Debug folder (by default) for your project. If it's Release mode, it's the /bin/Release folder, but as long as your working directory matches your application you can reference them in the Uri by file name alone (otherwise you'll need to check the application path and build the full path to the file).
The reason you need Content instead of Resource is in the Remarks section of the MediaPlayer class documentation:
When distributing media with your application, you cannot use a media file as a project resource. In your project file, you must instead set the media type to Content and set CopyToOutputDirectory to PreserveNewest or Always.
I'm writing a WPF app with VS2015. I have a User Control that contains an Image control. I have my image on the file system in an Images subfolder. In the Design mode, the image showed up fine, but when I ran it, it didn't. I specified the image location thus:
Source="Images/ball.png"
within the Image tag. I tried all the obvious things, like copying the folder to the bin\Debug folder and such. Experimenting, this error message popped up over the Source tag:
"Could not find a part of the path 'C:\Program Files (x86)\New folder\Microsoft Visual Studio 14.0\Common7\IDE\Images\red-ball.png'"
I finally got it to show up by giving it the FULL PATH to the image, but I really don't think I should have to. Isn't there a way to give it a relative path that's relative to the application and not the location of the IDE?
First, make sure that your Images subfolder is relative to your project ie:
Project
Images
ball.png
Then with "ball.png" added to your project, set its Build Action to "Resource". Your link will now work as you expect.
I'm guessing its looking for the image in the place you mentioned because it couldn't find it in the resources where it wants to look. Note that sounds and video clips do not work this way, you have to copy those to your build output or use a pack URI.
I have a VCXProj file for a Universal Windows app that compiles some xaml files
<Page Include="..\View\ViewModel.xaml" />
One result of this is the xaml file is deployed as part of the package as a resource: ms-appx:///AppNamespace/ViewModel.xaml
If the file path was instead "View\ViewModel.xaml" then the resource path would also be "AppNamespace/View/ViewModel.xaml"
Unfortunately, since it is in the parent directory, it gets flattened and goes in the root. I want a way to specify the output path, rather than let the MSBuild system preserve it, something like
<Page Include="..\View\ViewModel.xaml">
<TargetPath>View\MyViewModel.xaml</TargetPath>
</Page>
But I cannot for the life of me find a way to do this. Is there anything out there?
I think this is by design, I couldn't find an option in VS tool that can specify the output path of a xaml file.
By default if you create a View folder in your project from VS, and create a new Page in this View folder, the VS compiler will automatically extract this XAML file out of the View folder and put it in the root folder of your project folder. And even you created one folder in the project from VS, this folder will not be created actually in your project physical folder.
For example, I created a folder named "Test" from VS, and I copied an image into this folder. The path of this image is actually like this:<Image Include="C:\Users\(pc-account)\Pictures\1.jpeg" />, and you will not find the "Test" folder in the physical path of this project. Now if we create a folder also named "Test" in the physical path, not only from VS, and copy another image into this folder, open this project from you VS, right click the "Test" folder, by adding existing item to select the second image into this "Test" folder, then you can see from VS:
And in the Appx folder of your project it looks like this:
As you can see, the first image which is added to the project from VS is extracted from the Test folder to the root folder, and the second image which is manfully added to the project is still in the Test folder.
You can see the path of this two images in the VCXProj file like this:
I'm afraid there is no options in VS tool that can automatically do this work, we can only
manually create a folder with the same name as one created from VS tool.
copy the .xaml, .xaml.cpp, and .xaml.h file into this manually-created folder.
add existing item from vs to this folder.
debug your project then you can see this View2 folder in the Debug folder.
in the meanwhile, in your VCXProj file you can see this xaml page's path:
I have created a ClassLibrary project, and added a xaml of Window type.
I wrote a console application and showing this wpf window.
The problem is I have to show an Icon in this window.
If I am using following code it is not working
<Image Source="../Images/Folder-icon.png"></Image>
When I give some hard coded path like
<Image Source="E:\MyApp\Images\Folder-icon.png"></Image>
it works.
Why I have to give an hard coded path value? Is there any solution?
Hope I gave enough information. Please help I am struggling with this problem for more that 2 hours.
If Images folder is added in same project of its usage, this should work for you:
<Image Source="/Images/Folder-icon.png"/>
Or use Pack Uri specifically:
<Image Source="pack://application:,,,/Images/Folder-icon.png"/>
In case image resides in different project than current project where your XAML resides, you have to use more verbose definition of Pack URI where you have to specify the assembly name where image is added.
<Image Source="pack://application:,,,/Assembly;component/Images/Folder-icon.png"/>
Replace Assembly with actual assembly name where image is added into.
Also make sure Build Action is set to Resource for file Folder-icon.png.
UPDATE:
More verbose definition of Pack URI works in sample as well. Try this out:
<Image Source="pack://application:,,,/ClassLibrary1;component/Folder-icon.png"/>
Answers to such questions are often confusing because the principles/prerequisites for the solution to work are not explained correctly. This is the case with the currently selected answer too. So it's a good thing to be aware of:
The different ways to manage and reference a file/resource added to the project.
How to specify in the markup the URL for a file managed as Content.
The non-required use of the pack URI instead of the simple URL
Things to consider:
1. How to declare the type of file/resource you are adding to your project.
This is done by adding appropriate folder and files to the project using the Solution Explorer in VS, e.g. in a subfolder Images:
and specifying properties for each added file (on the right side below):
The Build Action is set to Content and the Copy To Output Directory is set to Copy if newer. This is how files should be added when you don't want them to be embedded into the assembly.
For reference, the Content option is one of the possible options to access a file in WPF. Other options include Resource (either embedded in the current assembly, or in another assembly of the same application) and Site of Origin to access a file which has no relationship with the current application:
Source
Content type files are linked to the executable (assembly) only by the relative path they are stored. The relative URL is stored in assembly metadata. These files are expected to be found at execution time, but they can be changed/updated without recompiling the assembly.
The Copy if Newer value means the compiler will take care of copying the original file to the right place during the assembly building process, so that the relative path is preserved, e.g. if a file is located in the subfolder Images of the project, e.g. MyProject/Images then a copy will be created in MyProject/bin/Debug/Images when the application is compiled in debug mode. The assembly being built in MyProject/bin/Debug, the relative path is the same.
2. How to specify a Content file URL in the markup.
This is the easy part, and usually the only one explained. But it works only if the previous step has been done correctly.
To use a content file, just use the markup shortcut of the relative path (relative to the assembly): <Image Source="Images/Lighthouse.jpg"/> (there is no leading /).
Other cases, where the file is not declared as Content type (e.g. an image which must be embedded into the assembly as a Resource, or a file which must be loaded from the network) involve syntax variations with the simple URL replaced by a pack URI.
3. Non-required / excessive use of the pack URI.
As the URI scheme can be used to reference anything, the pack URI solution is often proposed to also reference files declared as Content. For our example, the equivalent pack URI would be: pack://application:,,,/Images/Lighthouse.jpg (note the leading /).
However the URL shortcut is more appropriate, and less error-prone for a standalone file which location relative to the assembly is known at design time.
For a more detailed view see:
WPF Application Resource, Content, and Data Files
I got this working by:
Name of my WPF User Control project: WpfControls
Name of the folder containing the image: Images
Name of the imgae file: Asdf.png
Include the folder and image file into the WpfControls project
The image file's Build Action set to Resource
The Source property in the Image tag set to:
<Image Source=/WpfControls;Component/Images/Asdf.png" />