Как правильно выполнять навигацию по страницам при изменении выбора ListBox? - PullRequest
2 голосов
/ 05 августа 2010

Я пробую легкий инструментарий MVVM.Хотя я все еще думаю, что иметь несколько ViewModel для таких небольших приложений - это излишне, мне нравятся концепции.Что я до сих пор не могу понять, так это как (или я должен сказать «каков рекомендуемый способ») перемещаться с одной страницы на другую, когда выбор изменяется в ListBox.

Большая проблема с этим инструментариемзаключается в том, что он заставляет вас изучать MVVM из других источников, прежде чем использовать его, а не показывать вам, что (его видение) MVVM находится внутри фреймворка, сопровождая примеры и документацию.Есть ли образцы, показывающие различные концепции?И, пожалуйста, никаких видео.

Ответы [ 3 ]

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

Я до сих пор не понял, как это сделать (перейдите на страницу сведений после выбора, измененного в списке) без какого-либо кода в представлении. Однако, если у вас все в порядке с небольшим выделением кода, вот что я рекомендую:

<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}"
    SelectionChanged="MainListBox_SelectionChanged" 
    SelectedItem="{Binding Path=SelectedListItem, Mode=TwoWay}">
    <ListBox.ItemTemplate>
         <DataTemplate>
              <StackPanel Margin="0,0,0,17" Width="432">
                  <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                  <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
              </StackPanel>
        </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

Во-первых, в соответствии с приведенным выше привязкой к свойству SelectedItem Listbox с привязкой TwoWay к свойству в вашей ViewModel (SelectedListItem выше).

Тогда в вашем коде для этой страницы реализуйте обработчик для MainListBox_SelectionChanged:

    // Handle selection changed on ListBox
    private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // If selected index is -1 (no selection) do nothing
        if (MainListBox.SelectedIndex == -1)
            return;

        // Navigate to the new page
        NavigationService.Navigate(new Uri("/DetailsPage.xaml", UriKind.Relative));

    }

Это единственный код, который вам нужен на главном экране.

В вашей основной ViewModel вам необходимо свойство SelectedListItem:

    public const string SelectedListItemPropertyName = "SelectedListItem";
    private ItemViewModel _SelectedListItem;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding
    /// </summary>
    /// <returns></returns>
    public ItemViewModel SelectedListItem
    {
        get
        {
            return _SelectedListItem;
        }
        set
        {
            if (value != _SelectedListItem)
            {
                _SelectedListItem = value;
                RaisePropertyChanged(SelectedListItemPropertyName);
            }
        }
    }

Теперь, чтобы получить контекст, передаваемый на страницу сведений (контекст, являющийся тем, какой элемент списка был выбран), вам нужно настроить DataContext в представлении сведений:

public DetailsPage()
{
    InitializeComponent();
    if (DataContext == null)
        DataContext = App.ViewModel.SelectedListItem;

}

Надеюсь, это поможет.

1 голос
/ 22 марта 2012

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

Вот способ MVVM-light сделать это.

Сначала вы захотите связать выбранный элемент списка со свойством в вашей модели просмотра

<ListBox ItemsSource="{Binding Events}" Margin="0,0,-12,0" SelectedItem="{Binding SelectedEvent, Mode=TwoWay}">

Объявите вашу SelectedEvent собственность

    public const string SelectedEventPropertyName = "SelectedEvent";

    private Event _selectedEvent;


    public Event SelectedEvent
    {
        get {return _selectedEvent;}

        set
        {
            if (_selectedEvent == value)
            {
                return;
            }

            var oldValue = _selectedEvent;
            _selectedEvent = value;

            // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
            RaisePropertyChanged(SelectedEventPropertyName, oldValue, value, true);
        }
    }

Затем вы можете определить триггер взаимодействия, связанный с событием касания

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Tap">
        <cmd:EventToCommand Command="{Binding EventPageCommand, Mode=OneWay}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

В вашей модели представления определите свою EventPageCommand как RelayCommand:

public RelayCommand EventPageCommand { get; private set; }
public MainViewModel()
{
    EventPageCommand = new RelayCommand(GoToEventPage);
}

и, наконец, объявите свой GoToEventPage метод

private void GoToEventPage()
{
    _navigationService.NavigateTo(new Uri("/EventPage.xaml", UriKind.Relative));
}

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

1 голос
/ 05 августа 2010

Вы пытались изменить свой шаблон ItemBox ItemTemplate, чтобы каждый элемент был HyperlinkButton, и просто установить атрибут NavigateURI для страницы, к которой вы хотите перейти?

...