How do I reference a root directory in my WPF App? - c#

I'm instancing a Uri to be used as an image source but the string (file path) I'm providing is invalid. I understand why - it's because I'm using a relative path:
"Resources/Images/" + draggedAct.Category.ToLower() + ".png"
When I had this problem in asp .net I used Server.MapPath(imageString) to resolve the full path but I don't know the equivalent in WPF.
Thanks a lot,
Dan

use the pack uri syntax (see msdn: http://msdn.microsoft.com/en-us/library/aa970069%28v=vs.85%29.aspx):
"pack://application:,,,/Resources/Images/"+ draggedAct.Category.ToLower() +".png"
// Absolute URI (default)
Uri absoluteUri = new Uri("pack://application:,,,/Resources/Images/"+ draggedAct.Category.ToLower() +".png", UriKind.Absolute);
or:
// Relative URI
Uri relativeUri = new Uri("/Resources/Images/"+ draggedAct.Category.ToLower() +".png", UriKind.Relative);

You can use a pack URI, as described in the answer to this StackOverflow Question: Setting WPF image source in code

Related

Invalid URI: The format of the URI could not be determined - C#

Im trying to set the source of a resource dictionary in c# to a location of a folder within the project, but get the above error.
Could someone advise what the issue is please?
Heres the code:
myResourceDictionary.Source = new Uri("../Resources/Styles/Shared.xaml");
Please let me know if you need anymore information.
You have to use UriKind.Relative
myResourceDictionary.Source = new Uri("../Resources/Styles/Shared.xaml", UriKind.Relative);
I kept running into the same issue even after passing the UriKind.Relative argument. The weird bit was that some of the Uris to XAML pages were working using the method #Magnus suggested - but most of them would throw the:
The format of the URI could not be determined
exception.
Finally, I read up on Pack Uris for WPF applications which solved my problem a 100%.
I started using urls like this:
// ResourceFile is in the Root of the Application
myResourceDictionary.Source =
new Uri("pack://application:,,,/ResourceFile.xaml", UriKind.RelativeOrAbsolute);
or
// ResourceFile is in the Subfolder of the Application
myResourceDictionary.Source =
new Uri("pack://application:,,,/SubFolder/ResourceFile.xaml", UriKind.RelativeOrAbsolute);
Hope this helps someone struggling with the same issues I was facing.
I was trying to set the background of a window to an ImageBrush.
Changing UriKind.Absolute to UriKind.Relative fixed the problem for me.
private void SetBackgroundImage()
{
ImageBrush myBrush = new ImageBrush
{
ImageSource =
new BitmapImage(new Uri("background.jpg", UriKind.Relative))
};
this.Background = myBrush;
}

What is wrong with this URI?

Hej
I am trying to load an (embedded) image in a wpf application, using an Uri but I keep getting an exception.
The code is:
new BitmapImage(new Uri("pack://application:,,,,/Icons/m.png"));
(In case it isn't clear, I am trying to load the m.png file from the Icons folder, which
has been marked as an embedded ressource).
and the exception is
NotSupportetException (the URI prefix is not recognized)
Can anybody tell me what the uri should have been?
Three commas must be instead of four in your string:
new BitmapImage(new Uri("pack://application:,,,/LibName;component/Icons/m.png"));
LibName - points to assembly where resource is hosted.
You may take a look at this blog post. The solution is to register a custom uri parser so that it recognizes the pack protocol:
UriParser.Register(
new GenericUriParser(GenericUriParserOptions.GenericAuthority), "pack", -1
);

Uri for bitmap in subfolder (c# wpf)

I have a wpf app where I'm using an image. To reference the image I use:
Uri uri = new Uri("pack://application:,,,/assemblyName;Component/myIcon.png");
BitmapImage(uri)
If I add the png directly under the csproj file (with its properties BuildAction=Resource) then it works fine.
But I want to move it to a subfolder under the csproj. Another SO question asked about bitmaps\uri's (857732) and an answer linked to this msdn. So I tried :
Uri uri = new Uri("pack://application:,,,/assemblyName;Component/Icons/myIcon.png");
But that did not work.
Any ideas?
If the image is in your solution (i.e., you are not referencing the image from another assembly), you should be able to use this syntax:
Uri uri = new Uri("pack://application:,,,/Icons/myIcon.png", UriKind.Absolute);
Or, you can use a relative Uri as follows:
Uri uri = new Uri("/Icons/myIcon.png", UriKind.Relative);

How to open a WPF Content Stream?

Here's the code snippet
String str= ??????? // I want to assign c:/my/test.html to this string
Uri uri= new Uri (str);
Stream src = Application.GetContentStream(uri).Stream;
What's the correct way to do this? I'm getting "URI not relative" Exception thrown
Your problem is specific to WPF. See the Application.GetContentStream method.
You'll read that this method requires a relative URI. See "WPF Application, Resource, Content and Data files".
You have a file path - if you want to make it a URI add "file:///", ie. "file:///c:/my/test.html"
For local file URIs, you need to prefix it with:
file:///
I think you'll find your problem is that Application.GetContentStream is for a resource stream for a content data file that is located at the specified Uri. That is, deployed alongside an executable assembly.
If you look at: http://msdn.microsoft.com/en-us/library/aa970494(VS.90).aspx#Site_of_Origin_Files
You should find that the file:/// syntax as stated above is correct... But if you're going to open them you'll probably want some kind of switch to work out how to get the stream:
FileInfo fileToSave;
if (!existingFile.IsFile)
throw new ArgumentException("Input URI must represent a local file path", "existingFile");
fileToSave = new FileInfo(existingFile.LocalPath);
return fileToSave.Open(/* Args based on your needs */)
And similarly if it's a web URI:
if (!existingFile.Scheme.StartsWith("http"))
throw new ArgumentException("Input URI must represent a remote URL path", "existingFile");
// Do a WebRequest.Create call and attempt download... (Perhaps to MemoryStream for future use)
Hope that helps.
Andrew.

System.Uri fails to give correct AbsolutePath and LocalPath if the Path contains "#"

I have C# code that is trying to get the LocalPath for a executing assembly using the following line of code:
Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
This piece of code performs fine for all the variety of paths. It started to fail giving the right AbsolutePath and Localpath because the executing assembly path contained a # in it.
Assembly.GetExecutingAssembly().CodeBase gives "C:\c#\ExcelAddin1.1.0\GSRExcelPlugin\bin\Debug\Common.dll"
But new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath gives "C:\c" while it should have given "C:\c#\ExcelAddin1.1.0\GSRExcelPlugin\bin\Debug\".
Is there something that I need to handle or is there something wrong the way Uri class is used?
If this is a .net framework issue, how should I report this issue to Microsoft?
System.IO.FileInfo logger = new System.IO.FileInfo(Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath), "settings.config"));
Using EscapedCodeBase instead of CodeBase solves the problem. I dint realize that this was already handled until I stumbled on it.:)
The Uri class is behaving as expected. # is not a valid part of a url. Imo this is an issue with CodeBase property. It returns a string unescaping special characters rendering it pretty much unreliable. Your options are:
1) Always use EscapedCodeBase property instead.
var uri = new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath;
2) Or if you really have to deal with CodeBase property (if that is the only option), get the escaped part yourself.
var x = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var uri = x.LocalPath + Uri.UnescapeDataString(x.Fragment).Replace('/', '\\');
3) For file location of the loaded assembly, the easiest is to use Location property.
var uri = Assembly.GetExecutingAssembly().Location;
The issue has been reported several times, but MS insists that is how CodeBase is designed here, here, here and here.
I assume The URI functions are stripping away everything after the sharp # because it thinks its an anchor.
URI are designed for identifying resources on the internet, so your # character would be an illegal character in the middle of any URI.
Take even this question for example, the Title is
System.Uri fails to give correct AbsolutePath and LocalPath if the Path contains “#”
but the end of the URL has the "#" stripped away
system-uri-fails-to-give-correct-absolutepath-and-localpath-if-the-path-contains
Why do you need to convert it into a URI anyway. The only difference between these 3 console.writelines is the fact that the first two are prefixed with File:///
Console.WriteLine(Assembly.GetExecutingAssembly().CodeBase); // 1
Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
Console.WriteLine(uri); // 2
Console.WriteLine(uri.LocalPath); // 3

Categories