ClosDesign
ClosDesign

Reputation: 3924

Is it possible to load an external hosted XAML file into a WPF project?

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

Answers (2)

Michal Ciechan
Michal Ciechan

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

Leon Zhou
Leon Zhou

Reputation: 635

How about:

Application.Current.Resources.MergedDictionaries.Add(
    new ResourceDictionary { Source = uri }
);

Upvotes: 1

Related Questions