2013-08-31 33 views
3

我目前正在关注来自Microsoft虚拟学院的windows phone教程,其中一个挑战是使用在项目中创建并在运行时加载的设计xaml viewmodel 。在运行时加载xaml viewmodel与windows phone

经过几个小时的研究,我认为是时候诉诸于计算器,因为我没有得到任何地方。我已经阅读了很多文章,没有人给我一个正确的答案,所以我有几个问题:

  1. 如何解决我的错误?
  2. 如何在运行时以编程方式加载xaml模型视图?
  3. 如何使用xaml在运行时加载xaml模型视图?
  4. 凡调用XAML的装载在运行时

样本数据文件即SoundViewModelSampleData.xaml,看起来是这样的:

<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> 

最简单的代码以编程方式,我加载此发现:

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

虽然我可能在错误的位置调用它,现在,我发现了以下错误:

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]

假设我能解决这个错误,这将需要我的问题的护理1 & 2(固定错误并加载程序数据)

你能找出什么导致这个问题呢?

如上所述,我可能在加载应用程序时创建的错误位置,即从我的ViewModel中加载该位置。

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; 
    } 
} 

}

在我app.xaml.cs我有以下几点:

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

     return _soundViewModel; 
    } 
} 

现在怎么可以只使用XAML的运行时间和使用d我达到同样的:用于设计时的datacontext。

我读过几篇文章,但他们都为WPF,但大多数都涉及到装载用户控件,等等。但没有一个视图模型

任何帮助将不胜感激。

谢谢。

回答

3

我忙于解决与XamlReader相似的问题。我发现你应该在xaml文件的根元素中定义程序集名称空间,即使它包含在同一个程序集中。在下面的示例代码中,即使SoundBoard.dll中包含xaml,我也会在xaml文件中声明其名称空间。

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

嗨巴赫蒂,非常感谢!问题排序!我最终将XamlReader放入了app.xaml.cs中,但它感觉不太对劲!你知道更好的方法吗? – Thierry

1

也试过这样做,我会拿出最好的是移动数据XAML文件的资产,将其标记为资源(我删除的自定义工具为好),然后用加载以下:

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; 
     } 
    } 

我也做了什么Bahti建议。

+0

LoadData通常位于ViewModel中,所以你在哪里找到了你的位置?在app.xaml.cs中?我尝试了类似于你在我的视图模型中使用下面的代码的东西,this = XmalReader.Load,但它不喜欢它,所以我最终把这些代码放在app.xaml.cs中,但仍然没有喜欢它!从那里我可以设置静态SoundViewModel,可以在整个应用程序中访问。 – Thierry

+0

我不认为你可以分配给'this'-pointer。这就是为什么我要分配属性。我的LoadData函数在教程中创建的SoundModel类中。我也做了巴蒂提出的建议。 – Defeqel

+0

对不起,我错过了那部分,但我明白你的观点了!我会给你一枪!谢谢。 T. – Thierry