Reputation: 3924
Is it possible to load an external hosted XAML file into a WPF project? I am trying to pull in a ResourceDictionary from an external XAML file. I am doing this so I can style the application external from the application. I am doing this because I want to see if this is possible because the application is going to be running on multiple computers and I don't want to have to reload upload or load a new XAML file everytime I need to make a simple change to a button color or text color.
Below are 2 options I have tried but I keep getting that the resource can not be an absolute URI. Any pointers on how to make my XAML file load from an external hosted source?
Try one
namespace FunWithXaml
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
EnsureApplicationResources();
InitializeComponent();
}
public static void EnsureApplicationResources()
{
if (Current == null)
{
// create the Application object
// new Application();
// merge in your application resources
Current.Resources.MergedDictionaries.Add(
LoadComponent(
new Uri("http://example.com/scripts/XAMLTest.xml", //This can be .xaml or .xml from my understanding if it does not have the x:Class declared in the file.
UriKind.RelativeOrAbsolute)) as ResourceDictionary);
}
else
{
MessageBox.Show("Welp that didn't work.");
}
}
}
Try Two. Similar to above but I try to do it with using the WebClient and XamlReader. Not sure if I am doing this part correctly though.
var Blob = new Uri("http://example.com/scripts/XAMLTest.xml");
var wc = new WebClient();
var sourceStream = wc.OpenRead(Blob);
StreamReader mysr = new StreamReader(sourceStream);
FrameworkElement rootObject = XamlReader.Load(mysr.BaseStream) as FrameworkElement;
Current.Resources.MergedDictionaries.Add(LoadComponent(rootObject)); //rootobject is giving me red lined error.
And Try Three. Similar to Try One but completely did away with the "If" and get an error stating I can't have an absolute URI.
public static void EnsureApplicationResources()
{
Current.Resources.MergedDictionaries.Add(
LoadComponent(
new Uri("http://example.com/scripts/XAMLTest.xml",
UriKind.RelativeOrAbsolute)) as ResourceDictionary);
}
EDIT Try Four based on the suggestion below by @Leon Zhou. But I am getting an exception error:
"An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dll
Additional information: ResourceDictionary LoadFrom operation failed with URI 'http://example.com/scripts/XAMLTest.xml' ".
public App()
{
AFunction();
InitializeComponent();
}
public void AFunction()
{
var foo = new Uri("http://example.com/scripts/XAMLTest.xml", UriKind.Absolute);
Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = foo });
}
This what's in my XML file I am trying to pull.
<ResourceDictionary>
<Style x:Key="HeaderStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Green"/>
</Style>
</ResourceDictionary>
This is my App.xaml file
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="FunWithXaml.App"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--Trying to get dynamic XML/XAML resource to populate here-->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Upvotes: 0
Views: 1150
Reputation: 13888
var uri = new Uri("PathToMyXamlFile");
var stream = File.OpenRead(uri.ToString());
var resources = (ResourceDictionary)XamlReader.Load(stream);
I would get the Xaml as a String into a memory stream. And then give it to the XamlReader.Load.
Upvotes: 0
Reputation: 635
How about:
Application.Current.Resources.MergedDictionaries.Add(
new ResourceDictionary { Source = uri }
);
Upvotes: 1