WPF Prism Load XML in module - c#

i am experimenting with prism and the possibilities it brings to create applications divided into modules.
In one of my modules i want to load data from a XML file but can't get it to work so that
Uri uri = new Uri(resourceFile, UriKind.RelativeOrAbsolute);
StreamResourceInfo info = Application.GetResourceStream(uri);
will look for the file in the "Data" folder of my module project. Instead the file is successfully loaded if i put the "Data" folder with the XMl file inside the Shell project.
What do i miss?
Edit: value of resourceFile: "Data/file.xml"

finally got that to work:
Uri uri = new Uri("MainModule1;component/" + resourceFile, UriKind.Relative);
actually i did try that before but must have made a mistake.

Related

Getting DLL's 'Content' file from web app

I have a class library that has some text files with Build Action = Content. These text files are read by a function within the class library. To get the location of the text files I use this:
var filePath = System.IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"AFolder",
"textFileName.txt");
var fileContent = System.IO.File.ReadAllText(filePath);
I have successfully retrieved the content of the text file when I called the function from a unit test. The text file is in C:\MySolution\MyProject.Test\bin\Debug\AFolder\textFileName.txt.
I have another web app that references this class library. When I called the function to read the text file from the web app, it couldn't find the text file because it tried to get the file from C:\MySolution\MyProject.Web\AFolder\textFileName.txt while the text file is actually in C:\MySolution\MyProject.Web\bin\AFolder\textFileName.txt.
So my problem is calling AppDomain.CurrentDomain.BaseDirectory doesn't always work. What should I use instead to get the folder location?
Found the answer from the link on the right by using System.Reflection.Assembly.GetExecutingAssembly().CodeBase:
var libPath = System.IO.Path.GetDirectoryName(
new Uri(
System.Reflection.Assembly.GetExecutingAssembly().CodeBase
).LocalPath
);
var filePath = System.IO.Path.Combine(
libPath,
"AFolder",
"textFileName.txt");
var fileContent = System.IO.File.ReadAllText(filePath);
You can try System.WebHttpRuntime.BinDirectory to get the physical path to the /bin directory for the current application.
EDIT 1:
Another way to get without using System.Web is using AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, this property provides list of directories under the application base directory that are probed for private assemblies.

c# WPF URI syntax

I am just learning c# and have been struggling to work with URIs in WPF. I've googled around a fair bit but not having much luck.
Essentially I'm trying to have a BitmapImage object stored as a property in a Car object. I then want to display the BitmapImage in an Image control on a WPF form.
The app is a simple app (it's for a Uni assignment), so no database, etc.
I have two methods of doing this. The first is that I'm preloading Car data from a text file, including the filename of the JPG I want to load. I have included the JPG in a directory called Files which is off the main directory where my source code and class files are. I have set the JPG file to 'Content' and 'Always copy'. When I run a Debug, it copies the Files directory and the JPG to the debug\bin directory.
My code creates a BitmapImage by referring to the JPG using a URI as follows;
BitmapImage myImage = new BitmapImage (new Uri("Files/" + Car.Imagefilename, UriKind.Relative);
Car.Image = myImage;
ImageControl.Source = myImage;
If I step through this code in the debugger, it sometimes works and displays the image, but most of the time it doesn't.
My second method is when a user creates a new Car. This method always works. In this one, I use a file dialog box (dlg) to select the image and use an absolute path.
BitmapImage myImage = new BitmapImage (new Uri(dlg.Filename, UriKind.Absolute);
Car.Image = myImage;
ImageControl.Source = myImage;
So....I can't work out why the first method doesn't work. I think it's got something to do with the relative reference, but I can't work out how to syntax that properly to work. I've tried using "pack:,,,", I've tried adding "component", I've tried an '#' before the "pack". I can't seem to find something that explains this simply.
Apologies if this is straight forward but it's doing my head in! Appreciate any pointers.
If the image files are located in a "Files" folder of your Visual Studio project, you should set their Build Action to Resource (and Copy to Output Directory to Do not copy), and load them by a Resource File Pack URI:
var image = new BitmapImage(new Uri("pack://application:,,,/Files/" + Car.Imagefilename));
Car.Image = image;
ImageControl.Source = image;
There is no need to copy the files anywhere. Images are loaded directly from the assembly.
First try to load the image file using its absolute path. For example if the images are stored in c:\projects\yourproject\files, then try using something like
BitmapImage myImage = new BitmapImage (new Uri("c:/projects/yourproject/files/carname.jpg", UriKind.Absolute);
If it works, what you are facing is an path calculation issue.
At this point you may either calculate the Absolute with reference to your executable using AppDomain.CurrentDomain.BaseDirectory at runtime or use App.Config to store the path and reference it from there.
Cheers

How to get all files list from a relative URI in XAML application?

How to get all files from a folder in XAML application using relative path?
I am playing with a Kinect application built in WPF. All images used in the application are in
[project dir]\Images\ and all backgrounds are in
[project dir]\Images\Backgrounds\.
I want to get list of all the images from Backgrounds directory using relative path. I have tried
DirectoryInfo(#"\Images\Backgrounds\").GetFiles();
but it says that Backgrounds directory must exist in [full path+project dir]\debug\bin\
Selecting each image manually works fine
Uri uri = new Uri(#"Images\Backgrounds\Background1.png", UriKind.Relative);
ImageSource imgsource = new BitmapImage(uri);
this.Backdrop.Source = imgsource;
It works for a single file because you specify URI to resource embedded in the assembly and not some folder on your drive, whilst GetFiles() will work only on a specific physical folder. So either you need to copy all your images instead of embedding them or use the code below and resourceNames should give you names of all resources that you can reference by URI in your project:
List<string> resourceNames = new List<string>();
var assembly = Assembly.GetExecutingAssembly();
var rm = new ResourceManager(assembly.GetName().Name + ".g", assembly);
try
{
var list = rm.GetResourceSet(CultureInfo.CurrentCulture, true, true);
foreach (DictionaryEntry item in list)
resourceNames.Add((string)item.Key);
}
finally
{
rm.ReleaseAllResources();
}
if you need then at this point each item.Value contains UnmanagedMemoryStream for each resource.
I would reply to your post instead of posting a solution, but I'm new to this site and dont have that privledge yet.... Hey! Just trying to help.
Anyway, I've had a problem similar to this before concerning DirectoryInfo. Can't remember exactly how I solved it, but I remember the backslashes being tricky. Have you checked out the MSDN site? It seems like it can't find your directory so its looking for it in debug by default. MSDN says the format should be "MyDir\MySubdir" in C#.

can't Get stream of mp3 file in wp7 application

i'm building a wp7 application for a game using silverlight & XNA
i have an mp3 file called "Punch1.mp3" (Build action : resource ) stored inside a folder called "SoundEffects" inside the project folder
and i want to play the file using this code
StreamResourceInfo info;
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
punch is defined in the code here :
public static SoundEffect punch1;
the problem is that it raises a nullreference exception in the third line claiming that info is null
and that's true in the debugging mode , i found that the resource stream info is null
i think this is because the it can't read the file although the uri is correct
You can try two things
- Clean and rebuild the project
- Try appending project name in URI "/PhoneApp1;component/SoundEffects/Punch.mp3"
Since you're using the XNA assembly anyway, you can use TitleContainer.OpenStream instead (with a relative URI) and have the audio file build set as Content.
I agree with Haris Haqsan that your URI string is bad.
Uri myuri = new Uri("/PhoneBoxing;component/SoundEffects/Punch1.mp3", UriKind.Relative);
But you should also consider switching to using content files instead embedding them at resources as it can help your application start up time. Depending on the amount of files we are talking about, it can make a big difference.
Set your Build Action to content and your code should look like:
FileStream stream = new FileStream("/SoundEffects/Punch1.mp3", FileMode.Open, FileAccess.Read);
in the following code :
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
SoundEffect.FromStream() expects a wave file stream not an MP3 as shown here : http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.audio.soundeffect.fromstream.aspx .
so solution to find a mp3 > wav convertor or just find another way to load mp3 to WP7
considering the picture this is normal URI in normal cases can't evaluate expression of isfile .
I was experiencing the same issue on my machine, the InvalidOperationException is a little confusing. All I had to do was re-encode the wav file to the specifications listed on MSDN.
After I did that, it worked perfectly.

Load local HTML file in a C# WebBrowser

In my app I have a WebBrowser element.
I would like to load a local file in it.
I have some questions:
Where to place the HTML file (so that it will also be installed if a user executes the setup)
how to reference the file? (e.g. my guess is the user's installation folder would not always be the same)
EDIT
I've added the HTML file to my project.
And I have set it up so that it gets copied to output folder.
When I check it it is present when run: \bin\Debug\Documentation\index.html
However when I do the following I get a 'Page cannot be displayed' error in the webbrowser element.
I use the following code to try to display the HTML file in the Webbrowser.
webBrowser1.Navigate(#".\Documentation\index.html");
Do a right click->properties on the file in Visual Studio.
Set the Copy to Output Directory to Copy always.
Then you will be able to reference your files by using a path such as #".\my_html.html"
Copy to Output Directory will put the file in the same folder as your binary dlls when the project is built. This works with any content file, even if its in a sub folder.
If you use a sub folder, that too will be copied in to the bin folder so your path would then be #".\my_subfolder\my_html.html"
In order to create a URI you can use locally (instead of served via the web), you'll need to use the file protocol, using the base directory of your binary - note: this will only work if you set the Copy to Ouptut Directory as above or the path will not be correct.
This is what you need:
string curDir = Directory.GetCurrentDirectory();
this.webBrowser1.Url = new Uri(String.Format("file:///{0}/my_html.html", curDir));
You'll have to change the variables and names of course.
quite late but it's the first hit i found from google
Instead of using the current directory or getting the assembly, just use the Application.ExecutablePath property:
//using System.IO;
string applicationDirectory = Path.GetDirectoryName(Application.ExecutablePath);
string myFile = Path.Combine(applicationDirectory, "Sample.html");
webMain.Url = new Uri("file:///" + myFile);
Note that the file:/// scheme does not work on the compact framework, at least it doesn't with 5.0.
You will need to use the following:
string appDir = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().GetName().CodeBase);
webBrowser1.Url = new Uri(Path.Combine(appDir, #"Documentation\index.html"));
Place it in the Applications setup folder or in a separte folder beneath
Reference it relative to the current directory when your app runs.
Somewhere, nearby the assembly you're going to run.
Use reflection to get path to your executing assembly, then do some magic to locate your HTML file.
Like this:
var myAssembly = System.Reflection.Assembly.GetEntryAssembly();
var myAssemblyLocation = System.IO.Path.GetDirectoryName(a.Location);
var myHtmlPath = Path.Combine(myAssemblyLocation, "my.html");
What worked for me was
<WebBrowser Source="pack://siteoforigin:,,,/StartPage.html" />
from here. I copied StartPage.html to the same output directory as the xaml-file and it loaded it from that relative path.
Windows 10 uwp application.
Try this:
webview.Navigate(new Uri("ms-appx-web:///index.html"));
Update on #ghostJago answer above
for me it worked as the following lines in VS2017
string curDir = Directory.GetCurrentDirectory();
this.webBrowser1.Navigate(new Uri(String.Format("file:///{0}/my_html.html", curDir)));
I have been trying different answers from here, but managed to derive something working, here it is:
1- Added the page in a folder i created at project level named WebPagesHelper
2- To have the page printed by webBrowser Control,
string curDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
var uri = new Uri(curDirectory);
string myFile = Path.Combine(uri.AbsolutePath, #"WebPagesHelper\index.html");
Uri new_uri = new Uri(myFile);
i had to get the assembly path, create a first uri to get an absolute path without the 'file://' attached, next i combined this absolute path with a relative path to the page in its folder, then made another URI from the result.
Then pass this to webBrowser URL property webBrowser.URL = new_uri;

Categories