Qual é a maneira correta de executar a navegação de páginas nas alterações de seleção da caixa de listagem

StackOverflow https://stackoverflow.com/questions/3410915

  •  25-09-2019
  •  | 
  •  

Pergunta

Estou tentando o kit de ferramentas de luz MVVM. Embora eu ainda ache que ter vários viewmodels para aplicativos tão pequenos é um exagero, eu gosto dos conceitos. O que ainda não consigo entender é como (ou devo dizer "qual é a maneira recomendada") para navegar de uma página para outra quando a seleção mudar em uma caixa de listagem.

O grande problema com este kit de ferramentas é que ele o força a aprender MVVM por meio de outras fontes antes de usá -lo, em vez de mostrar o que (sua visão de) MVVM é de dentro da estrutura, acompanhando amostras e documentação. Existem amostras por aí mostrando os diferentes conceitos? E por favor, sem vídeos.

Foi útil?

Solução

Você já tentou modificar o seu ItemTemplate ItemTemplate para que cada item seja um hiperlinkbutton e apenas configurando o atributo Navigateuri para a página para a qual deseja navegar?

Outras dicas

Ainda não descobri como fazer isso (navegue para uma página de detalhes após a seleção alterada em uma caixa de listagem) sem nenhum código de código na visualização. No entanto, se você está bem em ter apenas um pouco de código de código na visão, aqui está o que eu recomendo:

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

Primeiro, por acima, vincule -se à propriedade selecionada da caixa de listagem com uma ligação twoway a uma propriedade em seu viewmodel (SelectedListItem no exposto acima).

Então, em seu código Codehind, para esta página, implemente o manipulador para 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));

    }

Este é o único CodeBehind que você precisa em sua visão principal.

Em sua principal viewModel, você precisa de uma propriedade selecionadaListItem:

    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);
            }
        }
    }

Agora, o truque para transmitir o contexto para sua página de detalhes (o contexto é qual item da lista foi selecionado) Você precisa configurar o DataContext na sua exibição de detalhes:

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

}

Espero que isto ajude.

Eventualmente, você desejará fazer mais do que apenas navegar, potencialmente navegar depois de definir um objeto personalizado.

Aqui está uma maneira da luz MVVM de fazer isso.

Você primeiro desejará vincular o item selecionado do seu ListBox a uma propriedade em seu viewmodel

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

Declarar seu SelectedEvent propriedade

    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);
        }
    }

Você pode definir um gatilho de interação ligado ao evento TAP

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

No seu ViewModel, defina seu evento de evento como um rendayCommand:

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

e finalmente declarar seu GoToEventPage método

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

Observe que você pode executar outras ações antes de navegar para a sua nova página, além de seu item selecionado na caixa de listagem está atualmente definido na propriedade que você a vinculou também.

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