在ListBox选择更改上执行页面导航的正确方法是什么

时间:2010-08-05 00:33:10

标签: windows-phone-7 mvvm-light

我正在尝试MVVM Light Toolkit。虽然我仍然认为为这样的小应用程序设置多个ViewModel是过度的,但我喜欢这些概念。我仍然无法理解的是,当ListBox中的选择发生变化时,如何(或者我应该说“建议的方式是什么”)从一个页面导航到另一个页面。

这个工具包的一个大问题是它迫使你在使用它之前通过其他来源学习MVVM,而不是向你展示MVVM的内容(它的愿景)来自框架,附带样本和文档。那里有样品展示了不同的概念吗?请,没有视频。

3 个答案:

答案 0 :(得分:1)

您是否尝试修改ListBox ItemTemplate以使每个项目成为HyperlinkBut​​ton,并将NavigateURI属性设置为您要导航到的页面?

答案 1 :(得分:1)

我仍然没有想到如何执行此操作(在列表框中选择更改后导航到详细信息页面),视图中没有任何代码隐藏。但是,如果您在视图中只有一点代码隐藏就可以了,这就是我的建议:

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

首先,上面绑定到Listbox的SelectedItem属性,并使用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);
            }
        }
    }

现在,将上下文传递给您的详细信息页面(上下文是选择了列表项)的技巧,您需要在Details视图中设置DataContext:

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

}

希望这有帮助。

答案 2 :(得分:1)

最终,您需要做的不仅仅是导航,可能在设置自定义对象后进行导航。

这是一种MVVM-light方式。

您首先要将列表框选定项目绑定到viewmodel

中的属性
<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>

在viewmodel中,将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));
}

请注意,您可以在导航到新页面之前执行其他操作,此外,列表框中的所选项目当前也会在您绑定的属性中设置。