Есть ли способ вызвать Navigate из ViewModel? - PullRequest
7 голосов
/ 16 сентября 2010

У меня есть проект Silverlight 4, который отображает диаграмму и некоторые кнопки, позволяющие пользователю изменять диапазон дат диаграммы. Диапазон дат также может быть передан через параметр строки запроса - что-то вроде http://myserver/MySilverlightPage/#?DateRange=OneMonth - и когда пользователь нажимает кнопку, я также хотел бы обновить URL-адрес.

Я понимаю, что способ сделать это - позвонить по номеру this.NavigationService.Navigate(new Uri(...)), но, насколько я могу судить, это можно сделать только из кода страницы Silverlight. А поскольку я использую MVVM, вся обработка команды происходит в классе ViewModel. Есть ли способ вызвать Navigate или иным образом изменить URL-адрес из ViewModel?

Чтобы уточнить, xaml включает в себя следующее Button:

<Button Content="1 Month View"
        Command="{Binding OneMonthCommand}" />

А класс ViewModel содержит свойство OneMonthCommand:

public ICommand OneMonthCommand { get; set; }

Когда кнопка нажата, вызывается метод Execute моей реализации ICommand. Вопрос в том, как я могу изменить URL из этого метода?

Ответы [ 3 ]

8 голосов
/ 17 сентября 2010

Я обнаружил, что это является распространенной проблемой в приложениях Silverlight, которые я пишу с использованием шаблона MVVM. Я использую класс NavigationHelper для централизации логики вокруг навигации. Это выглядит примерно так:

public interface INavigationHelper
{
    void Home();
    void SomeOtherPage();
}

public class NavigationHelper : INavigationHelper
{
    private NavigationService _navSvc;

    public NavigationHelper(NavigationService navSvc)
    {
        _navSvc = navSvc;
    }

    public void Home()
    {
        _navSvc.Navigate(new Uri("/Home", UriKind.Relative));
    }

    public void SomeOtherPage()
    {
        _navSvc.Navigate(new Uri("/SomeOtherPage", UriKind.Relative));
    }
}

Тогда у меня у ViewModel есть свойство NavigationHelper, которое устанавливается страницей при создании ViewModel.

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

2 голосов
/ 17 сентября 2010

Если вы просто делаете обычную навигацию, вы должны использовать обычные кнопки гиперссылки.Если вы пытаетесь перемещаться в ответ на другие события, тогда вы можете использовать обмен сообщениями.

В качестве альтернативы можно сделать так, чтобы View передавал класс NavigationService вашей ViewModel, и если вы используете базовую страницу иБазовая модель представления. Вы сможете добиться того, чтобы это происходило в тех случаях, когда не требуется каждая модель представления и представление, зная о происходящей передаче.

1 голос
/ 17 сентября 2010

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

Проблема, как вы обнаружили, в NavigationService.Navigate заключается в том, что для ее контекста требуется знание страницы a.

Я не думаю, что считается "слишком злым", чтобы внедрить ваше текущее представление обратно в его модель представления, когда вы устанавливаете текст данных в codebehind. Как правило, для View хуже знать слишком много о его ViewModel.

...