Question

I'm currently following a windows phone tutorial from Microsoft virtual academy and one of the challenges was to use the design xaml viewmodel that was created in the project and loaded at run-time.

After researching this for hours, I thought it was time to resort to stackoverflow as I'm not getting anywhere. I've read numerous articles and none are giving me a correct answer, so I've got a few questions:

  1. How to fix my error?
  2. How to load the xaml model view at run-time programmatically?
  3. How to load the xaml model view at run-time using xaml?
  4. Where to call the loading of the xaml at run-time

The sample data file i.e. SoundViewModelSampleData.xaml, looks like this:

<vm:SoundViewModel
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:Soundboard.ViewModels"
    xmlns:mo="clr-namespace:Soundboard.Models">

    <vm:SoundViewModel.Animals>
        <vm:SoundGroupViewModel Title="Animals Sample">
            <vm:SoundGroupViewModel.Items>
                <mo:SoundDataModel Title="Animals 1" FilePath="Animals.wav" />
            </vm:SoundGroupViewModel.Items>
        </vm:SoundGroupViewModel>
    </vm:SoundViewModel.Animals>
    <vm:SoundViewModel.Cartoons>
        <vm:SoundGroupViewModel Title="Cartoons Sample">
            <vm:SoundGroupViewModel.Items>
                <mo:SoundDataModel Title="Cartoons 1" FilePath="Cartoons.wav" />
                <mo:SoundDataModel Title="Cartoons 2" FilePath="Cartoons.wav" />
            </vm:SoundGroupViewModel.Items>
        </vm:SoundGroupViewModel>
    </vm:SoundViewModel.Cartoons>
</vm:SoundViewModel>

The simplest code to load this programmatically that I found was:

string path = @".\SampleData\SoundViewModelSampleData.xaml";
using (System.IO.StreamReader reader = new System.IO.StreamReader(path))
{
    SoundViewModel vm = XamlReader.Load(reader.ReadToEnd()) as SoundViewModel;
}

While I'm probably calling it from the wrong location for now, I'm getting the following error:

A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in System.Windows.ni.dll

{System.Windows.Markup.XamlParseException: Unknown parser error: Scanner 2147500037. [Line: 5 Position: 14] at MS.Internal.XcpImports.CreateFromXaml(String xamlString, Boolean createNamescope, Boolean requireDefaultNamespace, Boolean allowEventHandlers, Boolean expandTemplatesDuringParse, Boolean trimDeclaredEncoding) at System.Windows.Markup.XamlReader.Load(String xaml) at Soundboard.ViewModels.SoundViewModel.LoadData()}

Unknown parser error: Scanner 2147500037. [Line: 5 Position: 14]

Assuming I can resolve this error, this would take care of my question 1 & 2 (fixing error and loading the data programmatically)

Can you spot what's causing this problem?

As mentioned above, I'm probably loading this in the wrong place i.e. from within my ViewModel when it is created when the app loads.

namespace Soundboard.ViewModels
{
    public class SoundViewModel
    {
        public SoundGroupViewModel Animals { get; set; }
        public SoundGroupViewModel Cartoons { get; set; }

        public bool IsDataLoaded { get; set; }

        public void LoadData()
        {
            string path = @".\SampleData\SoundViewModelSampleData.xaml";
            using (System.IO.StreamReader reader = new System.IO.StreamReader(path))
            {
                SoundViewModel vm = System.Windows.Markup.XamlReader.Load(reader.ReadToEnd()) as SoundViewModel;
        }
        IsDataLoaded = true;
    }
}

}

And in my app.xaml.cs I have the following:

public static SoundViewModel SoundViewModel
{
    get
    {
        if (_soundViewModel == null)
        {
            _soundViewModel = new SoundViewModel();
            _soundViewModel.LoadData();
        }

        return _soundViewModel;
    }
}

Now how can I achieve the same using just xaml for the run-time and use d:datacontext for design-time.

I've read a few articles but they are all for wpf but most are related to loading usercontrol, etc.. but not a viewmodel

Any help would be greatly appreciated.

Thanks.

Was it helpful?

Solution

I was busy on a similar problem as yours with XamlReader. I found that you should define the assembly namespace in the root element of your xaml file even if it is included in the same assembly. In the example code below even if the xaml is included in SoundBoard.dll, I declare its namespace in the xaml file.

xmlns:vm = "clr-namespace:SoundBoard.ViewModels;assembly=SoundBoard">

OTHER TIPS

Also tried doing this and the best I could come up with was to move the data XAML file to assets, mark it as a Resource (I removed the Custom Tool as well), and then load it with the following:

    public void LoadData()
    {
        // Load data
        //LoadCodeData();
        LoadXamlData();

        IsDataLoaded = true;
    }

    private void LoadXamlData()
    {
        string path = "SoundBoard;component/assets/runtimecontent/SampleData.xaml";
        Uri uri = new Uri(path, UriKind.Relative);
        using (System.IO.StreamReader reader = new System.IO.StreamReader((System.Windows.Application.GetResourceStream(uri)).Stream))
        {
            SoundModel model = System.Windows.Markup.XamlReader.Load(reader.ReadToEnd()) as SoundModel;
            this.Animals = model.Animals;
            this.Cartoons = model.Cartoons;
            this.Taunts = model.Taunts;
            this.Warnings = model.Warnings;
            this.CustomSounds = model.CustomSounds;
        }
    }

I also did what Bahti suggested.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top