Caliburn Micro управление контентом навигация - PullRequest
0 голосов
/ 30 октября 2019

Я использую caliburn micro для этого проекта. У меня есть ShellView с моим contentcontrol:

<ContentControl x:Name="ActiveItem"
                        Grid.Row="0" Grid.Column="0" />

В ShellViewModel я получил его, чтобы показать свой userControl LoginView с помощью:

 public class ShellViewModel : Conductor<object>
    {
        public ShellViewModel()
        {
            ActivateItem(new LoginViewModel());
        }

        public void ShowSignUp()
        {
            ActivateItem(new SignUpViewModel());
        }
    }

Однако я не могу перейти к SignUpView из LoginView смоя кнопка:

<!-- Row 4 -->
<Button x:Name="ShowSignUp"
        Content="Sign Up Now!"
        Grid.Row="3" Grid.Column="1"
        Style="{StaticResource LoginBtnsStyle}" />

LoginViewModel, полученная из ShellViewModel:

public class LoginViewModel : ShellViewModel
    {

    }

Как мне перейти от LoginView к SignUpView с помощью кнопки, которая находится на LoginView? Я не получаю ошибок, это просто не меняет представление. Я также попытался поместить ShowSignUp () в LoginViewModel, но безуспешно.

Обновление 1 ShellViewModel:

public class ShellViewModel : Conductor<object>, IHandle<ActionInvokedMessage>
    {
        DispatcherTimer dt = new DispatcherTimer();
        private SplashScreenViewModel _splashVM;
        private LoginViewModel _loginVM;
        private SignUpViewModel _signUpVM;
        private IEventAggregator _eventAggregator;

        public ShellViewModel(SplashScreenViewModel splashVM, LoginViewModel loginVM, SignUpViewModel signUpVM)
        {
            _loginVM = loginVM;
            _signUpVM = signUpVM;
            _splashVM = splashVM;
            ActivateItem(_splashVM);

            dt.Tick += new EventHandler(Dt_Tick);
            dt.Interval = new TimeSpan(0, 0, 2);
            dt.Start();
        }

        private void Dt_Tick(object sender, EventArgs e)
        {
            dt.Stop();
            ActivateItem(_loginVM);
        }

        public ShellViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
            _eventAggregator.Subscribe(this);
            ActivateItem(new LoginViewModel(_eventAggregator));
        }

        public void Handle(ActionInvokedMessage message)
        {
            ActivateItem(message.Page);
        }

        public void ShowSignUp()
        {
            ActivateItem(new SignUpViewModel());
        }



    }

Ответы [ 2 ]

0 голосов
/ 31 октября 2019

Вы можете создать интерфейс для навигации и использовать его в моделях представления для навигации по приложению.

interface INavigation {
    void NavigateTo(System.Type typeId);
}

class ShellViewModel: Conductor<object>,  INavigation  {

    private List<object> pages = new List<Object>();

    public ShellViewModel() {
        pages.Add(new SignupViewModel(this));
        pages.Add(new LoginViewModel(this));
    }

    void NavigateTo(System.Type typeId) {
        var page = pages.Where(x => x.GetType() == typeId).FirstOrDefault()
        ActivateItem(page);
    }
}

class SignupViewModel {
    public SignupViewModel(INavigation navigation) {
        this.ShowLoginCommand= new NavigateCommand<LoginViewModel>(navigation);
    }
}

class LoginViewModel {
    public LoginViewModel (INavigation navigation) {
        this.ShowSignUpCommand = new NavigateCommand<SignupViewModel>(navigation);
    }
}

Команда навигации может быть реализована следующим образом:

public class NavigateCommand<T> : ICommand
{
    public event EventHandler CanExecuteChanged;
    private readonly INavigation navigation;

    public NavigateCommand(INavigation navigation)
    {
        this.navigation = navigation;
    }

    public bool CanExecute(object parameter) => true;
    public void Execute(object parameter) => this.navigation.NavigateTo(typeof(T));
}

Здесь я передаюSystem.Type, но вы можете создать тип, который лучше описывает запрос навигации, чтобы вы могли передавать дополнительные параметры.

0 голосов
/ 30 октября 2019

Этого можно добиться, используя EventAggregator , чтобы публиковать показательные сообщения из LoginViewModel в ShellViewModel для обновления пользовательского интерфейса.

Для начала вам нужно определить класс сообщения, который сообщит ShellViewModel, какую ViewModel необходимо изменить. Например,

public class ActionInvokedMessage
    {
        public Screen Page { get; set; }
    }

Свойство Page указывает, какой экран необходимо загрузить. Теперь вы можете изменить свой LoginViewModel следующим образом:

public class LoginViewModel: Screen
    {
        private IEventAggregator _eventAggregator;
        public LoginViewModel(IEventAggregator eventAggregator)
        {

            _eventAggregator = eventAggregator;
            _eventAggregator.Subscribe(this);
        }

        public void ShowSignUp()
        {
            _eventAggregator.PublishOnUIThread(new ActionInvokedMessage { Page = new SignupViewModel() }); ;
        }
    }

Метод PublishOnUIThread будет передавать сообщение всем слушателям типа сообщения ActionInvokedMessage для изменения. Следующим шагом было бы убедиться, что ShellViewModel будет прослушивать изменение.

public class ShellViewModel : Conductor<object>, IHandle<ActionInvokedMessage>
    {
        private IEventAggregator _eventAggregator;
        public ShellViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
            _eventAggregator.Subscribe(this);
            ActivateItem(new LoginViewModel(_eventAggregator));
        }

        public void Handle(ActionInvokedMessage message)
        {
            ActivateItem(message.Page);
        }

        public void ShowSignUp()
        {
            ActivateItem(new SignupViewModel());
        }


    }

Реализация интерфейса IHandle позволяет нам обрабатывать действие, которое потребуется выполнить, когда ShellViewModel получит ActionInvokedMessage. Как видно из кода, это подходящее место для использования метода ActivateItem для загрузки страницы регистрации.

...