我目前正在关注Microsoft虚拟学院的Windows手机教程,其中一个挑战是使用在项目中创建并在运行时加载的设计xaml viewmodel。
经过几个小时的研究,我认为现在是时候采用stackoverflow了,因为我没有到达任何地方。我读了很多文章,没有人给我一个正确的答案,所以我有几个问题:
示例数据文件,即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;
}
虽然我现在可能从错误的位置调用它,但我收到以下错误:
类型的第一次机会异常 'System.Windows.Markup.XamlParseException'发生在 System.Windows.ni.dll
{System.Windows.Markup.XamlParseException:未知的解析器错误: 扫描仪2147500037. [线:5位置: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()}
未知的解析器错误:扫描程序2147500037. [行:5位置:14]
假设我可以解决此错误,这将解决我的问题1&amp; 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的,但大多数都与加载usercontrol等有关..但不是viewmodel
非常感谢任何帮助。
感谢。
答案 0 :(得分:3)
我和XamlReader一样忙于解决类似的问题。我发现你应该在你的xaml文件的根元素中定义程序集名称空间,即使它包含在同一个程序集中。在下面的示例代码中,即使xaml包含在SoundBoard.dll中,我也会在xaml文件中声明其命名空间。
xmlns:vm = "clr-namespace:SoundBoard.ViewModels;assembly=SoundBoard">
答案 1 :(得分: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所建议的。