我使用MVVM方法构建了 Silverlight 应用程序。 在我的ViewModel中,只有在用户使用LoggedIn 后才能加载一些数据,所以我需要拦截此事件以触发我的LoadData()。 使用默认配置,我的意思是在App.xaml.cs中:
public App()
{
InitializeComponent();
// Create a WebContext and add it to the ApplicationLifetimeObjects
// collection. This will then be available as WebContext.Current.
WebContext webContext = new WebContext();
webContext.Authentication = new FormsAuthentication();
//webContext.Authentication = new WindowsAuthentication();
this.ApplicationLifetimeObjects.Add(webContext);
如果您尝试在ViewModel构造函数中订阅LoggedIn或LoggedOut事件,则会遇到一些问题:WebContext尚不存在。
所以我想......我先创建我的WebContext,然后在我的应用程序中使用InitializeComponents(),但这会让ExpressionBlend感到悲伤......
所以,这是我的解决方案,我想与你分享,因为我并不完全相信这是正确的方法:
App.Current.Startup += (sender, eventArgs) =>
{
WebContext.Current.Authentication.LoggedIn += WebContext_LoggedIn;
WebContext.Current.Authentication.LoggedOut += WebContext_LoggedOut;
};
在我的ViewModel ctor中,我订阅App.Current.Startup,我的委托将订阅我的ViewModel到Login事件,这样我没有更改我的App.xaml.cs,我肯定在WebContext时订阅Login事件存在... 所以:
private void WebContext_LoggedIn(object sender, AuthenticationEventArgs e)
{
LoadData();
}
修改
在这种情况下,当我说我不应该改变InitializeComponent()与其余部分之间的顺序并且我需要监听特定事件时,我更感兴趣的是理解我是否正确触发我的LoadData()。
为了完整起见,我的重构是在我的ViewModel中摆脱这种依赖:
我创建了一条消息:
public class UserLoginStatusChangedMessage : MessageBase
{
public bool IsLoggedIn { get; set; }
}
发送到这里:
private void Application_Startup(object sender, StartupEventArgs e)
{
// This will enable you to bind controls in XAML files to WebContext.Current
// properties
this.Resources.Add("WebContext", WebContext.Current);
// This will automatically authenticate a user when using windows authentication
// or when the user chose "Keep me signed in" on a previous login attempt
WebContext.Current.Authentication.LoadUser(this.Application_UserLoaded, null);
// Show some UI to the user while LoadUser is in progress
this.InitializeRootVisual();
WebContext.Current.Authentication.LoggedIn += (s, a) =>
{
Messenger.Default.Send(new UserLoginStatusChangedMessage
{ IsLoggedIn = true });
};
WebContext.Current.Authentication.LoggedOut += (s, a) =>
{
Messenger.Default.Send(new UserLoginStatusChangedMessage
{ IsLoggedIn = false });
};
}
并在ViewModel ctor中收到它:
Messenger.Default.Register<UserLoginStatusChangedMessage>(this, msg =>
{
if (msg.IsLoggedIn)
{
LoadData();
}
});
答案 0 :(得分:1)
我建议使用某种在用户登录时发送消息的信使类.MVVMLight有一个易于使用的nice messenger class。然后,您只需在用户登录状态发生变化时发送消息,并在视图模型中订阅该事件,该事件需要知道用户是否已登录。
您可以检查WebContext以查看它是否已创建,如果用户在创建viewmodel时登录,则会创建它,然后只需使用这些消息来确定是否/何时更改。