Вопрос

Попытка использовать окно входа с Caliburn + MEF

Я также получаю эти два предупреждения, а также

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
.

Спасибо заранее, я знаю, что Кальберн собирается сэкономить мне много времени, хотел бы получить это на работу!

В этом проекте мой ISHELL - это пустой интерфейс.

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>
.

Это было полезно?

Решение

На самом деле Роб Айзенберг из caliburn мне очень помог, и он помог мне с этой проблемой.

Проблема заключалась в том, что, когда я переключился на калибровку, первым открывшимся окном был LoginView, и он был закрыт до открытия окна MainView.

windows рассматривает первое открытое окно как главное окно.и когда главное окно закрыто, окна проверяют, открыты ли другие окна, если не закрывают приложение.

Он предоставил возможное решение: создать оболочку loginviewmodel и закрыть ее после открытия mainviewmodel.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top