Pergunta

tentando usar uma janela de login com caliburn + mef

Eu também recebo esses dois avisos

Warning    1    CA2000 : Microsoft.Reliability : In method 'AppBootstrapper.CreateContainer()', call System.IDisposable.Dispose on object 'container' before all references to it are out of scope.    C:\adl\DotNetProjects\CaliburnTest\CaliburnTest\AppBootstrapper.cs    25    CaliburnTest
Warning    2    CA2000 : Microsoft.Reliability : In method 'AppBootstrapper.CreateContainer()', call System.IDisposable.Dispose on object 'new AggregateCatalog(Enumerable.Select<Assembly, AssemblyCatalog>(this.SelectAssemblies(), AppBootstrapper.CS$<>9__CachedAnonymousMethodDelegate1))' before all references to it are out of scope.    C:\adl\DotNetProjects\CaliburnTest\CaliburnTest\AppBootstrapper.cs    25    CaliburnTest

Agradeço antecipadamente, sei que o caliburn vai me poupar muito tempo. Adoraria fazer isso funcionar!

Neste projeto, meu IShell é uma interface vazia.

public class AppBootstrapper : Bootstrapper<IShell>
{
    protected override IServiceLocator CreateContainer()
    {
        var container = new CompositionContainer(
            new AggregateCatalog(SelectAssemblies().Select(x => new AssemblyCatalog(x)))
            );

        var batch = new CompositionBatch();
        //batch.AddExportedValue<IWindowManager>(new WindowManager());
        return new MEFAdapter(container);
    }
}



[Export(typeof(IShell))]
public class MainViewModel : Conductor<IScreen>, IShell
{
    readonly IWindowManager windowManager;
    [ImportingConstructor]
    public MainViewModel(IWindowManager windowManager)
    {
        this.windowManager = windowManager;
        var result = windowManager.ShowDialog(new LoginWindowViewModel());
        if (result != true)
        {
            Application.Current.Shutdown();
        }
    }
}

[Export(typeof(LoginWindowViewModel))]
public class LoginWindowViewModel :Screen
{
    public LoginWindowViewModel()
    {
    }
    public  ObservableCollection<User> Users
    {
        get
        {
            if (_users == null)
            {
                _users = new ObservableCollection<User>(){new User("ADMIN","ADMIN","ADMIN")};
            }
            return _users;
        }
    }

    public bool AuthenticateUser(string username, string pass)
    {
        Common.Authenticated.CurrentUser = Users.Where<User>(y => y.Login.Trim() == username.Trim()).FirstOrDefault(y => y.Pass.Trim() == pass.Trim());
        if (Common.Authenticated.CurrentUser != null)
            return true;
        return false;
    }
    public bool Authenticated 
    {
        get
        {
            if (Username == null || Username == String.Empty || Password == null || Password == String.Empty)
                return false;
            return AuthenticateUser(Username, Password); 
        }
    }
    public bool CheckAuthNeeded() {return true;}
    private ObservableCollection<User> _users;

    public void Login()
    {    RequestClose(this, new SuccessEventArgs(true));      }
    public string Username {get;set;}
    public string Password {get;set;}

    public event CloseDialogEventHandler RequestClose;
      public delegate void CloseDialogEventHandler(object sender, SuccessEventArgs e);
}

<"LoginWindowView:

<Grid Height="Auto" Width="Auto">
    <Grid.RowDefinitions>
        <RowDefinition Height="2*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="93*" />
        <ColumnDefinition Width="185*" />
    </Grid.ColumnDefinitions>
    <StackPanel Grid.Column="0" Margin="10,10,0,0">
        <Label Content="Username:"  FontWeight="Bold" VerticalContentAlignment="Center" Margin="0,4,0,0" Padding="5,5,0,5" />
        <Label Content="Password:"  FontWeight="Bold" VerticalContentAlignment="Center" VerticalAlignment="Stretch" Margin="0,4,0,0" Padding="5,5,0,5" />
    </StackPanel>
    <StackPanel Grid.Column="1" Margin="0,10,10,0">
        <dxe:ComboBoxEdit x:Name="User" ItemsSource="{Binding Users}" 
                         Padding="0" Margin="5" DisplayMember="Login" ValueMember="Login" Validate="User_Validate" ValidateOnTextInput="True"
                          AutoComplete="True" ImmediatePopup="True"   IncrementalFiltering="True" ShowEditorButtons="False" />
        <dxe:PasswordBoxEdit x:Name="Pass" Margin="5" Validate="Pass_Validate" ValidateOnTextInput="False"  InvalidValueBehavior="AllowLeaveEditor" />
    </StackPanel> 
    <Button Content="Login" Grid.Row="1" Height="23" HorizontalAlignment="Center" 
            x:Name="Login" VerticalAlignment="Top" Width="75" IsDefault="True" Grid.ColumnSpan="2" />
</Grid>

LoginWindowView CodeBehind:

public partial class LoginWindowView
{
    public LoginWindowView()
    {
        InitializeComponent();
    }
    private void User_Validate(object sender, ValidationEventArgs e)
    {

        if (e.Value == null)
        {
            e.IsValid = false;
            return;
        }
        var _vm = GetDataContext();
        var u = _vm.Users.FirstOrDefault<User>(x => x.Login.Trim() == ((string)e.Value).Trim().ToUpper());

        if (u == null)
        {
            e.SetError("Invalid Login Name", DevExpress.XtraEditors.DXErrorProvider.ErrorType.Information);
            _vm.Username = string.Empty;
            e.IsValid = false;
        }
        else
            _vm.Username = User.Text;
    }
    public LoginWindowViewModel GetDataContext()
    {
        return (LoginWindowViewModel)DataContext;
    }
    private void Pass_Validate(object sender, ValidationEventArgs e)
    {
        if (e.Value == null)
        {
            e.IsValid = false;
            return;
        }
        var _vm = GetDataContext();
        _vm.Password = ((string)e.Value).ToUpper();
        if (_vm.Authenticated == false)
        {
            e.SetError("Wrong Password.", DevExpress.XtraEditors.DXErrorProvider.ErrorType.Critical);
            e.IsValid = false;
        }
    }
    private void Window_Closed(object sender, EventArgs ee)
    {
        GetDataContext().RequestClose -= (s, e) =>
        {
            this.DialogResult = e.Success;
        };
    }
    private void Window_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (e.OldValue != null)
        {
            ((LoginWindowViewModel)e.OldValue).RequestClose -= (s, ee) =>
            {
                this.DialogResult = ee.Success;
            };
        }
        ((LoginWindowViewModel)e.NewValue).RequestClose += (s, ee) =>
        {
            this.DialogResult = ee.Success;
        };
    }
}

public class User
{
    public string FullName { get; private set; }
    public string Login { get; private set; }
    public string Pass { get; private set; }

    public User(string fullName, string login, string pass) { FullName = fullName; Login = login; Pass = pass; }
    public static User CreateUser(string fullName, string login,string pass)
    {
        return new User(fullName, login,pass);
    }
}




    public static class Authenticated
    {
        public static string AuthString { get; set; }
        public static User CurrentUser { get; set; }
        public static string UserId
        {
            get
            {
                if (CurrentUser != null)
                    return CurrentUser.Login;
                return string.Empty;
            }
        }
    }

<✓MainView:

<Window x:Class="CaliburnTest.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainView" Height="300" Width="300">
    <Grid>
        <Label>Test</Label>
    </Grid>
</Window>

Foi útil?

Solução

Na verdade, Rob Eisenberg de Caliburn foi muito útil e ele me ajudou com essa questão.

O problema foi que quando eu mudei para o CALIBURN, o LogInview foi a primeira janela a ser aberta e foi fechada antes que a janela principal foi aberta.

Windows trata a primeira janela aberta como o mainwindow.e quando o mainwindow é fechado verificações do Windows se outras janelas estão abertas, caso não feche o aplicativo.

Ele forneceu uma possível solução de fazer o loginviewModel o shell e fechando-o após abrir o manualVemmodel.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top