2014-12-27 125 views
0

我有一個Windows 8.1應用程序,我試圖向左側添加一個動態生成的菜單。我檢索一個MenuItem列表(定義如下),我想在左側創建一個菜單,當你點擊MenuItem時,它需要將其他view/flipview/frame導航到關聯的頁面與菜單項。我使用MVVM Light並設置了我的導航服務,但它僅導航主框架,並且我只希望頁面上的子視圖發生更改。WinRT XAML菜單導航MVVM

例如,當您單擊左側的菜單項時,我希望「DestinationPage」顯示在右側。我需要將它與List或集合關聯,因爲每個用戶都有不同的MenuItem列表。

此外,我知道這可以通過代碼隱藏來完成,但我想堅持使用MVVM並讓ViewModel處理哪個頁面屬於該子視圖。謝謝。

public class MenuItem : IMenuItem 
{ 
    public string Name { get; set; } 
    public Type DestinationPage { get; set; } 
} 

這是我的ViewModel

public class CustomerDetailsViewModel : BaseViewModel 
{ 
    private string _detailPageSource; 
    private MenuItem _selectedMenuItem; 


    public MenuItem SelectedMenuItem 
    { 
     get { return _selectedMenuItem; } 
     set { Set(() => SelectedMenuItem, ref _selectedMenuItem, value); } 
    } 

    public RelayCommand<MenuItem> MenuItemSelectedCommand { get; private set; } 

    public ObservableCollection<IMenuItem> Details { get; set; } 

    public CustomerDetailsViewModel() 
    { 

     MenuItemSelectedCommand = new RelayCommand<MenuItem>(m => DetailPageSource = m.DestinationPageLocation); 

     Details = new ObservableCollection<IMenuItem>() 
     { 
      new MenuItem() 
      { 
       DestinationPage = typeof (Demographics), 
       Name = "Demographics" 
      }, 
      new MenuItem() 
      { 
       DestinationPage = typeof(OrderProductList), 
       Name = "Test Another Type" 
      } 
     }; 

     SelectedMenuItem = Details.Single(m => m.Name == "Demographics") as MenuItem; 
    } 

Example where gray area is navigation and blue area is separate view

實施例,其中用於導航和藍色區域的灰色區域中的一個圖是對內容

回答

0

我能夠解決這個問題單獨的視圖通過執行以下操作:

  1. 添加FlipView控件的頁面
  2. 綁定FlipView的菜單項集合
  3. 創建MenuItemDataTemplateSelector

我的代碼如下:

的XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="80*"></RowDefinition> 
     <RowDefinition Height="20*"></RowDefinition> 
    </Grid.RowDefinitions> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="20*"></ColumnDefinition> 
      <ColumnDefinition Width="80*"></ColumnDefinition> 
     </Grid.ColumnDefinitions> 
     <StackPanel Orientation="Vertical" Background="LightGray"> 
      <TextBlock FontSize="20" HorizontalAlignment="Center">Customer Details</TextBlock> 
      <ListView ItemsSource="{Binding Details}" 
         SelectedItem="{Binding SelectedMenuItem, Mode=TwoWay}"> 
       <ListView.ItemTemplate> 
        <DataTemplate> 
         <Grid> 
          <TextBlock Text="{Binding Name}" /> 
         </Grid> 
        </DataTemplate> 
       </ListView.ItemTemplate> 
      </ListView> 
     </StackPanel> 

     <FlipView Grid.Column="1" ItemTemplateSelector="{StaticResource MenuNameDataTemplateSelector}" 
        ItemsSource="{Binding Details, Mode=TwoWay}" 
        SelectedItem="{Binding SelectedMenuItem, Mode=TwoWay}"> 
      <FlipView.Resources> 
       <DataTemplate x:Key="Demographics"> 
        <details:Demographics /> 
       </DataTemplate> 
       <DataTemplate x:Key="Order History"></DataTemplate> 
       <DataTemplate x:Key="Communication Settings"></DataTemplate> 
       <DataTemplate x:Key="Alerts"></DataTemplate> 
       <DataTemplate x:Key="Order Product List"> 
        <views:OrderProductList /> 
       </DataTemplate> 
      </FlipView.Resources> 
     </FlipView> 


    </Grid> 

MenuItemDataTemplateSelector

public class MenuNameDataTemplateSelector : DataTemplateSelector 
{ 
    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) 
    { 
     var menuItem = item as MenuItem; 
     var element = container as FrameworkElement; 
     if (menuItem != null || element != null) 
     { 
      while (element != null) 
      { 
       while (element != null) 
       { 
        if (element.Resources.ContainsKey(menuItem.Name)) 
        { 
         var template = element.Resources[menuItem.Name] as DataTemplate; 
         if (template != null) 
          return template; 
        } 
        else 
        { 
         element = VisualTreeHelper.GetParent(element) as FrameworkElement; 

         if (element == null) 
          element = element.Parent as FrameworkElement; 
        } 
       } 
      } 
     } 
     return base.SelectTemplateCore(item, container); 
    } 
} 

和視圖模型

public class CustomerDetailsViewModel : BaseViewModel 
{ 
    private string _detailPageSource; 
    private MenuItem _selectedMenuItem; 


    public MenuItem SelectedMenuItem 
    { 
     get { return _selectedMenuItem; } 
     set { Set(() => SelectedMenuItem, ref _selectedMenuItem, value); } 
    } 

    public RelayCommand<MenuItem> MenuItemSelectedCommand { get; private set; } 

    public ObservableCollection<IMenuItem> Details { get; set; } 

    public CustomerDetailsViewModel() 
    { 

     Details = new ObservableCollection<IMenuItem>() 
     { 
      new MenuItem() 
      { 
       DestinationPage = typeof (Demographics), 
       Name = "Demographics" 
      }, 
      new MenuItem() 
      { 
       DestinationPage = typeof(OrderProductList), 
       Name = "Order Product List" 
      } 
     }; 

     SelectedMenuItem = Details.Single(m => m.Name == "Demographics") as MenuItem; 
    } 

    public override void ClearViewModel() 
    { 
     throw new NotImplementedException(); 
    } 
}