【问题标题】:WinRT XAML Menu Navigation MVVMWinRT XAML 菜单导航 MVVM
【发布时间】:2014-12-27 02:13:53
【问题描述】:

我有一个 Windows 8.1 应用程序,我正在尝试在左侧添加一个动态生成的菜单。我检索 MenuItem 列表(定义如下),我想制作一个左侧有菜单的页面,当您单击 MenuItem 时,它需要将其他视图/flipview/frame 导航到关联的页面与菜单项。我正在使用 MVVM Light 并设置了我的导航服务,但它只导航主框架,我只希望页面上的子视图发生变化。

例如,当您单击左侧的菜单项时,我希望“DestinationPage”显示在右侧。我需要将其与列表或集合相关联,因为每个用户都有不同的 MenuItem 列表。

此外,我知道这可以通过代码隐藏来完成,但我想坚持使用 MVVM 并让 ViewModel 处理哪个页面属于该子视图。谢谢。

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

这是我的视图模型

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

示例,其中灰色区域的导航视图和蓝色区域是内容的单独视图

【问题讨论】:

    标签: c# mvvm navigation windows-runtime winrt-xaml


    【解决方案1】:

    我能够通过执行以下操作来解决此问题:

    1. 向页面添加 FlipView 控件
    2. 将 FlipView 绑定到 MenuItem 集合
    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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-10
      • 1970-01-01
      • 2014-09-21
      • 2018-02-14
      • 2017-05-23
      • 2016-06-23
      相关资源
      最近更新 更多