问题描述
|
和往常一样,我正在尝试使用一项新技术,并立即遇到问题。
我有一个Silverlight业务应用程序+ MvvmLight。
在我的视图模型中,我尝试获取登录用户的角色:
public Homeviewmodel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
// Code runs \"for real\"
DetermineStartableProcesses();
}
}
private void DetermineStartableProcesses()
{
_startableProcesses = new ObservableCollection<WorkflowProcess>(
WebContext.Current.User.Roles.SelectMany(r =>
WorkflowProcess.GetStartableByRole(r))
.distinct());
}
在运行时,出现以下异常:
System.Windows.Markup.XamlParseException occurred
Message=The invocation of the constructor on type \'CompanyHR.viewmodel.viewmodelLocator\' that matches the specified binding constraints threw an exception. [Line: 18 Position: 57]
LineNumber=18
LinePosition=57
StackTrace:
at System.Windows.Application.LoadComponent(Object component,Uri resourceLocator)
at CompanyHR.App.InitializeComponent()
at CompanyHR.App..ctor()
InnerException: System.ArgumentNullException
Message=Value cannot be null.
Parameter name: source
StackTrace:
at System.Linq.Enumerable.SelectMany[TSource,TResult](IEnumerable`1 source,Func`2 selector)
at CompanyHR.viewmodel.Homeviewmodel.DetermineStartableProcesses()
at CompanyHR.viewmodel.Homeviewmodel..ctor()
at CompanyHR.viewmodel.viewmodelLocator..ctor()
InnerException:
看起来viewmodelLocator正在创建Webcontext get之前在应用启动时实例化viewmodel,这意味着在viewmodel构造函数中做很多工作对我来说是个坏主意。
因此,我应该在viewmodel中的哪个位置检索将获得数据绑定的数据?
解决方法
在App构造函数中实例化WebContext。然后在调用之前将其添加到App_startup中的资源中
public App()
{
Startup += Application_Startup;
Exit += Application_Exit;
UnhandledException += Application_UnhandledException;
if (IsInDesignModeStatic)
{
Services.ServiceLoader.LoadDesignTimeServices();
DispatcherHelper.Initialize();
}
else
{
try
{
ServiceLoader.LoadRunTimeServices();
DispatcherHelper.Initialize();
WebContext webContext = new WebContext();
ApplicationLifetimeObjects.Add(WebContext.Current);
FormsAuthentication fa = new FormsAuthentication();
fa.DomainContext = new Web.Services.AuthenticationDomainContext();
WebContext.Current.Authentication = fa;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
InitializeComponent();
}
private void Application_Startup(object sender,StartupEventArgs e)
{
this.Resources.Add(\"WebContext\",WebContext.Current);
RootVisual = new MainPage();
}
我发现由于我的自定义AuthenticationDomainContext和Membershipprovider使得在后面的代码中执行此部分更容易...但是Dereks也很好用,我在使所有工作正常的同时使用了后面的代码。
,这就是我在使用mvvm-light时避免的方式。因此,首先创建WebContext。
在App.xaml中:
<Application.ApplicationLifetimeObjects>
<ct:WebContext>
<ct:WebContext.Authentication>
<as:FormsAuthentication DomainContextType=\"MyProj.Data.AuthenticationContext,MyProj.Client.Common,Version=1.0.0.\" />
</ct:WebContext.Authentication>
</ct:WebContext>
</Application.ApplicationLifetimeObjects>
<Application.Resources>
<ResourceDictionary>
<ct:ViewModelLocator x:Key=\"Locator\"
d:IsDataSource=\"True\" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source=\"Assets/Styles.xaml\" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>