У меня есть приложение Silverlight , спроектированное с использованием подхода MVVM. В моей ViewModel пора загружать некоторые данные только после того, как пользователь вошел в систему , поэтому мне нужно перехватить это событие, чтобы вызвать мою 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);
Если вы попытаетесь подписаться на события LoggedIn или LoggedOut в конструкторе ViewModel, вы получите несколько проблем: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 на события входа в систему, таким образом я не изменил свой App.xaml.cs, и я обязательно подпишусь на события входа в систему, когда существует WebContext ...Итак:
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();
}
});