Guidance for implementing a login screen in WPF

Jan 24, 2012 at 6:09 PM

Hi,

I would be interested if anyone had some guidance on how to meet the following requirements

I am working on a WPF project where the first screen needs to be a Login screen, which will also allow the user to select the database to use. After which the application shell needs to load.

Currently I am exporting the EntityManagerProvider in the AppBootstrapper as follows.

batch.AddExportedValue<IEntityManagerProvider<MyDB>>(new�EntityManagerProvider(connectionDetails));

 

I need to collect the connection details before I hit the above point or delay exporting the value until the login screen is completed by the user.

I have tried the following all of which fail:

Display the login window within the AppBootstrapper, get object not set error

Make the LoginViewModel the start-up window, but can’t close the login screen without closing the app.

Display the login window within the ShellViewModel OnActivate method; get error - cannot set Owner property to a Window that has not been shown previously.

 

Thanks
Chris

Coordinator
Jan 24, 2012 at 7:46 PM

From the top of my head, without any abstraction.

 

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using Caliburn.Micro;
using Caliburn.Micro.Extensions;
using IdeaBlade.Application.Framework.Core.Authentication;
using IdeaBlade.Application.Framework.Core.Persistence;
using IdeaBlade.EntityModel;
 
namespace LoginDemo
{
    [ExportPartCreationPolicy(CreationPolicy.Shared)]
    public class ConnectionSettings
    {
        public string DataSourceExtension { getset; }
    }
 
    [Export(typeof (IEntityManagerProvider<NorthwindIBEntities>))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class EntityManagerProvider : BaseEntityManagerProvider<NorthwindIBEntities>
    {
        private readonly ConnectionSettings _connectionSettings;
 
        [ImportingConstructor]
        public EntityManagerProvider(ConnectionSettings connectionSettings)
        {
            _connectionSettings = connectionSettings;
        }
 
        protected override NorthwindIBEntities CreateEntityManager()
        {
            return new NorthwindIBEntities(dataSourceExtension: _connectionSettings.DataSourceExtension);
        }
    }
 
    [Export]
    public class LoginViewModel : Screen
    {
        private readonly IAuthenticationService _authenticationService;
        private readonly ConnectionSettings _connectionSettings;
 
        [ImportingConstructor]
        public LoginViewModel(ConnectionSettings connectionSettings, IAuthenticationService authenticationService)
        {
            _connectionSettings = connectionSettings;
            _authenticationService = authenticationService;
        }
 
        // Action bound to button in view for example
        public void Login()
        {
            _connectionSettings.DataSourceExtension = "..."// set with user selected data source
            _authenticationService.Login(new LoginCredential("""""")); // or better yet use LoginAsync
            TryClose();
        }
    }
 
    [Export]
    public class ShellViewModel : Conductor<IScreen>
    {
        private readonly Lazy<LoginViewModel> _loginViewModel;
        private readonly IWindowManager _windowManager;
 
        [ImportingConstructor]
        public ShellViewModel(IWindowManager windowManager, Lazy<LoginViewModel> loginViewModel)
        {
            _windowManager = windowManager;
            _loginViewModel = loginViewModel;
        }
 
        protected override void OnViewLoaded(object view)
        {
            base.OnViewLoaded(view);
 
            // Main window has been created at this point. Save to display login window
            _windowManager.ShowDialog(_loginViewModel.Value);
        }
    }
 
    public class AppBootstrapper : FrameworkBootstrapper<ShellViewModel>
    {
        protected override void InitializeCompositionBatch(CompositionBatch batch)
        {
            base.InitializeCompositionBatch(batch);
            batch.AddExportedValue<IAuthenticationService>(new AuthenticationService<NorthwindIBEntities>());
        }
    }
}
Jan 25, 2012 at 8:51 PM

That worked.

Thanks