.net 在将WebContext添加到ApplicationLifetimeObjects或等待App.Current.Startup事件之前,是否初始化组件()?
我有一个使用MVVM方法构建的Silverlight应用程序在我的ViewModel中,只有在用户登录后才能加载一些数据,因此我需要截获此事件以触发我的LoadData()。 使用默认配置,我在App.xaml.cs中的意思是:.net 在将WebContext添加到ApplicationLifetimeObjects或等待App.Current.Startup事件之前,是否初始化组件()?,.net,silverlight,architecture,.net,Silverlight,Architecture,我有一个使用MVVM方法构建的Silverlight应用程序在我的ViewModel中,只有在用户登录后才能加载一些数据,因此我需要截获此事件以触发我的LoadData()。 使用默认配置,我在App.xaml.cs中的意思是: public App() { InitializeComponent(); // Create a WebContext and add it to the ApplicationLifetimeObjects
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,然后在我的应用程序中初始化Components(),但这让ExpressionBlend很伤心
因此,这是我的解决方案,我想与大家分享,因为我不完全相信这是正确的方法:
App.Current.Startup += (sender, eventArgs) =>
{
WebContext.Current.Authentication.LoggedIn += WebContext_LoggedIn;
WebContext.Current.Authentication.LoggedOut += WebContext_LoggedOut;
};
在我的ViewModel中,我订阅了App.Current.Startup,我的代理将订阅我的ViewModel登录事件,这样我就没有更改我的App.xaml.cs,并且我确信在WebContext存在时订阅登录事件。。。
因此:
编辑
在这种情况下,我更感兴趣的是,当我说我不应该更改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中以如下方式接收:
Messenger.Default.Register<UserLoginStatusChangedMessage>(this, msg =>
{
if (msg.IsLoggedIn)
{
LoadData();
}
});
Messenger.Default.Register(此消息=>
{
如果(msg.IsLoggedIn)
{
LoadData();
}
});
我建议使用某种messenger类,在用户登录时发送消息。MVVMLight具有易于使用的。然后,当用户的登录状态发生变化时,您只需发送一条消息,并在视图模型中订阅该事件,该事件需要知道用户是否已登录
您可以检查WebContext,查看它是否已创建,如果用户在创建viewmodel时登录,它是否已创建,然后使用消息确定是否/何时更改。谢谢您的回答,是的,我通常使用messenger来完成这些事情,在本例中肯定更好。。。否则我就要打破这种模式了。在这种情况下,我更感兴趣的是理解我说的不应该更改InitializeComponent()和其余部分之间的顺序,并且我需要侦听某个特定事件来触发我的LoadData()时是否正确。我觉得您编辑的代码很好。如果只在不处于设计模式的情况下加载WebContext,可能会让Blend更快乐。MVVMLight也有一种方法来检查这一点。
Messenger.Default.Register<UserLoginStatusChangedMessage>(this, msg =>
{
if (msg.IsLoggedIn)
{
LoadData();
}
});