How Can I Use WebView.NavigateToString in MVVM Pattern Without Code-Behind? - c#

I need my app to dynamically load and display locally stored html files at runtime. Because of UWP sandbox, binding a WebView source to a URI will not work unless the location is in appdata. These html files contain base64 embedded video thus are large, so copying to the Local folder each time would result in a delay from the disk write operation.
My workaround idea is to load the file into memory and use WebView.NavigateToString or WebView.NavigateToStreamUri. But these would need to be invoked from the code-behind which of course would break the clean MVVM pattern I'm going for. I'm not just being an MVVM purist, I want to be able to load user provided XAML files as "skins" at runtime and can't do that if I have to call these methods in the code-behind. Are there any solutions I haven't thought of?

Related

WKWebView - Xamarin code to extract, store and display web page along the resources (img, font, js, css etc.) for offline viewing

Is there any library in Xamarin which would store the pages that we browse in WKWebView?
Have to store the resources of the pages (CSS, fonts, js etc.) for offline viewing. The complexity is maintaining the folder structure and manage the resource Urls within the CSS and JS files. Any idea how the resources can be stored and loaded?
There are resources on how to save a html page and load the html in WKWebView.
Please note that this question is not about that. It is more about storing and managing the resources of the visited pages for offline viewing.
I don't think you're going to get your answer with a mobile only approach. It's not impossible to create one but I don't believe anything exists that will do what you want, happy to be proven wrong. I think you need to think outside the square a bit.
I can't give you the entire set of code because I don't own it (my company does) but I managed to take a website completely offline (with limitations of course) by using multiple resources to achieve the desired outcome.
I used a piece of software called Cyotek WebCopy in an Azure VM to scrape all of the website down to a folder. That folder was then zipped up and uploaded to Azure Blob Storage so it could be accessed from anywhere. The Xamarin app would then access the storage container, retrieve all of the blobs and then when a user clicks on a specific blob, it unzips down to the device and then opens up in a web view for the user to browse.
All of this was achieved using a web service and PowerShell scripts on the VM side and then of course your standard Xamarin based application for viewing.
Like I said, there are limitations to this but barring external links and database calls (like a submission page), it will work for you. It has worked for us.
It may sound like a lot of work but all in all, the VM side took me about 2 days and the Xamarin concept about 5 so all in all, not long to stand something up that is able to be built upon. I hope that helps.

Display local images in UWP WebView control

I need to write the code which will load some HTML (received from external source by other means) into WebView and display images referenced in this HTML. These images will be stored locally somewhere in Windows.Storage.ApplicationData.Current.LocalFolder.
Neither of suggestions at use local image to display in webview for windows phone 8.1 or Use local images in Webbrowser control work for me. If I load such HTML with web.NavigateToString(html):
<html><head></head><body>A <img src="file:///c:/Users/idh/AppData/Local/Packages/d783af9f-88eb-42f5-ab0f-abb025f32baa_5cy2zb9g43kb2/LocalState/folder/image001.jpg"> B</body></html>
I get just A B displayed. I tried slashes and backslashes, double and triple slashes after file:, ms-appx: and relative paths instead of file:, etc. The image never gets displayed. At the same time, if I save this in HTML file and open it outside of my app, it's displayed fine. I also successfully save and read these files (they are actually appeared in that folder because my app created them so unauthorized access is not an issue). package.manifest does include Private networks.
I'd better not use embedding with base64, custom uri resolver and other special techniques because I'm not the actual developer of the application. I make a library which gets HTML and saves images to local storage and now I need to demonstrate an easy to use method to visualize the stored content in WebView like I earlier did for normal .NET framework. I.e. I'm actually writing a sample for developers who are users of my library and these folks will then use my sample to deal with this HTML and images.
As the last resort, I can end up writing base64 or custom resolver for UWP version of my sample (while for other platforms like normal .NET framework the same procedure is much easier). But I want to at least be sure that the direct route of selecting proper URLs for images in the source HTML is not possible and I won't end up with situation where I wrote some quite complicated stuff and then someone experienced in UWP apps reveals that I over-engineered things. I.e. some expert opinion "no, it's not possible in UWP and you MUST use base64 embedding or custom URI resolving" will work for me too.
Although NavigateToString supports content with references to external files such as CSS, scripts, images, and fonts. But it only supports content in the app package using the ms-appx-web scheme, and web content using the http and https URI schemes. It can't work with assets located in the apps local folder. So using file:///, ms-appdata:/// or ms-appx:/// scheme won't work here.
To achieve what you want, you can use Base64 encoded images or custom URI resolver. Also I think you can store the html string to a file under the same subfolder that stores these image assets. In the html, you can use relative URI to reference these assets like what in my previous answer. And then use the Navigate method with a Uri that uses the ms-appdata scheme. For example:
var html = "<html><head></head><body>A <img src=\"image001.jpg\"> B</body></html>";
var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("folder", CreationCollisionOption.OpenIfExists);
var file = await folder.CreateFileAsync("html.html", CreationCollisionOption.OpenIfExists);
await FileIO.WriteTextAsync(file, html);
webView.Navigate(new Uri("ms-appdata:///local/folder/html.html"));

C# Working with Images - Resources or Imagepath

i am wondering, what's the best way of working with images in c#, in a wpf application.
Someone recommend to pass the path of the image to the application, and someone recommend to use resources.
In my current project i have a listview and whenever i click a button, a image will be added. I am working with a ObservableCollection and whenever i click a button, i add the path of the image to the collection.
So, whenever i start the application i run throug the folder with the images and collect the names in an array. This way i can create the complete path to the image.
After that i use a method to shuffle the array values.
I don't know exactly how i can do that with resources, because i can't access the path of the files, but i can directly access the image.
What would you recommend, using the path or resources, and how would you handle it? What's about the performance?
I searched a lot but didn't find an answer for my "problem", maybe i used the wrong keywords...
For "After that I use a method to shuffle the array values." just use some prefix or similar to root through the resources and throw whatever you need into a collection and apply your shuffling there. All you really need to track is the name. Using Resources will be more space efficient and adds a bit more safety into things.

Using the res:// protocol with System.Windows.Forms.WebBrowser

I'm trying to use a resource (html file) located in a dll. With WinForms WebBrowser, when I navigate to the file, nothing happens, while with included AxSHDocVw.dll and SHDocVw.dll and AxWebBrowser, it works. Is the WinForms WebBrowser control somehow restricted or something? Can I make it to run res://?
See my post here: https://stackoverflow.com/a/15672462/1413201.
The basic gist is there are two types of resources in code files. You need to include a C style resource script to use the res protocol. Navigation errors are probably turned off in the WebBrowser control and therefore you don't see an error.
You can use the res protocol with IE to test if the resource is actually in the file and a C style resource editor just to double double check.
What I would assume, is that for security reasons, WinForms' WebBrowser control doesn't handle res:// links. It would make it very easy for someone to access resources which are contained within your DLLs which you may not want accessed.
If you want to implement the functionality yourself, then I'd recommend looking at the Assembly class and its use. It shouldn't be hard to parse a res:/// into your DLL path, load the assembly, search for the given resource and return that for the WebBrowser control.

write the contents of application page to a file in WP7

I want to write the entire contents of my application page (eg Mainpage.xml) to a file (in Isolated Storage ) How do I do it in WP7 ? are there any methods available to parse the page contents and write it to file in windows phone 7 ?
There is no built in way to do this.
However there are a couple of approaches you could try:
If the structure is static you could try and extract the resource containing this from the DLL. For future re-use it would be easier to load the page from the DLL again though.
If you're generating a page (or part of a page) at runtime (based on user input/preferences) and you want to be able to save/reload this then just save enough information to be able to recreate it. It's unlikely that XAML would be the best format for this though.
You could create this as you build the UI. Alternatively you could walk the visual tree to get details of all that is rendered. I'd recommend recording as you go so you can more easily keep track of non-default values in the rendered objects.

Categories