none
Как создать меню в Windows Store приложениях?

    Вопрос

  • Всем доброго времени суток!

    Задача стоит такая.

    У меня есть несколько Frame в приложении(App1.xaml,App2.xaml, App3.xaml). Соответственно на каждой странице свой функционал, не зависимый от функционала других страниц. Мне нужно эти страницы объединить одним меню которое должно располагаться в верху каждой страницы. Что бы находясь на странице App1 я мог перейти на страницы App2 и App3, а перейдя на одну из этих страниц мог либо вернуться, либо перейти опять на другую страницу.

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

    21 июня 2013 г. 10:04

Ответы

  • А я настаиваю на использовании AppBar. Во-первых он не занимает место всегда и у вас больше места для контента. Во-вторых даже в нем уже что то есть, никто не мешает расширить его функционал и сделать подсветку текущего пункта так же не проблема.

    +1.

    Полное описание решения здесь.

    Здесь приведу выдержки. Добавляем в проект UserControl. С вот таким XAML:

    <UserControl
        x:Class="App3.MyMenu"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App3"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">    
        <ListView x:Name="lvMain">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <TextBlock>Главная</TextBlock>
            <TextBlock>Первая</TextBlock>
            <TextBlock>Вторая</TextBlock>
        </ListView>
    </UserControl>

    И вот таким кодом:

    public sealed partial class MyMenu : UserControl
    {
        public MyMenu()
        {
            this.InitializeComponent();
            Loaded += MyMenu_Loaded;
        }
    
        Type[] pages = { typeof(MainPage), typeof(BlankPage1), typeof(BlankPage2) };
    
        void MyMenu_Loaded(object sender, RoutedEventArgs e)
        {
            Page currentPage = GetCurrentPage();
            lvMain.SelectedIndex = pages.TakeWhile(p => p != currentPage.GetType()).Count();
            lvMain.SelectionChanged += lvMain_SelectionChanged;
        }
    
        void lvMain_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Page currentPage = GetCurrentPage();
            if (currentPage.GetType() != pages[lvMain.SelectedIndex])
            {
                currentPage.Frame.Navigate(pages[lvMain.SelectedIndex]);
            }
        }
    
        private Page GetCurrentPage()
        {
            FrameworkElement element = this;
            while (element != null && element.Parent != null && !(element.Parent is Page))
            {
                element = element.Parent as FrameworkElement;
            }
            Page currentPage = element.Parent as Page;
            return currentPage;
        }
    }

    На страницы добавляем наш контрол:

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" /> <!--Здесь будет меню-->
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <local:MyMenu />
        <TextBlock Grid.Row="1"  Text="Это главная страница" FontSize="20" />
    </Grid>

    Работает вот так:

    • Помечено в качестве ответа Ercheph 21 июня 2013 г. 13:03
    21 июня 2013 г. 12:55
    Отвечающий

Все ответы

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

    Кстати, если я прав с первым предположением, то почитайте вот это, если еще не читали.

    21 июня 2013 г. 10:25
    Отвечающий
  • Я имею в виду именно первое. AppBar я знаю как добавлять.

    А можно по подробнее как создавать свой UserControl. Потому что перейдя по ссылке которую вы дали, я нашел только как создать страницу и дочернюю страницу  с кнопкой назад. Но это не то. Задача в том что бы сделать меню как на WEB-сайтах когда у них в шапке есть меню которое присутствует на всех страницах и позволяет переходить по разделам. 

    21 июня 2013 г. 10:44
  • 1. Правый клик на проекте

    2. Add New Item -> User Control

    3. Пишите XAML, код.

    4. Компилируете проект.

    5. Переходите на страницы в которых вам нужно меню и перетаскиваете с панели Tools (где готовые компоненты: кнопки, текстбоксы и т.д.) на форму. В XAML правите свойства.

    P.s. Ссылка была дана для того, чтобы вы прочитали, что в Windows Store приложениях такой вид навигации не приветствуется. Уж лучше сделайте как в IE:

    21 июня 2013 г. 10:52
    Отвечающий
  • Похоже мы не можем понять друг друга. Попробую объяснить на примере. Есть приложение Twitter для Windows 8, у которого в левой части приложения есть меню (как показано на картинке). Это 4 разные страницы с четырьмя разными возможностями. При клике на одном из пунктов нас перебрасывает на одну из страниц приложения. При этом делает подсветку того пункта на странице которого мы находимся. И по этому меню можно переходить от одной страницы к любой другой.

    Или я не могу понять что нужно сделать. Можете тогда дать ссылку на страницу где есть пример решения такой проблемы. Я просто найти ничего подобного не могу.

    P.S. И делать как в IE не вариант, верхний appbar уже занят. Да и нижний тоже.

    21 июня 2013 г. 11:20
  • Если позволите, то я бы не делал при таком дизайне несколько страниц. У меня бы была одна страница с фиксированным с лева меню и в правой части был бы ContentControl, в который, в зависимости от выбранного пункта подставлялся нужный контрол.

    Ну а как делать в вашем случае, давайте вечером подробный пример напишу (если раньше никто не поможет), сейчас времени нет...

    21 июня 2013 г. 11:46
    Отвечающий
  • Не вопрос! Буду ждать. 

    P.S. Дизайн приложения у меня совсем другой, меню будет не сбоку а сверху в одном из ячеек Grid. Просто Twitter первым мне попался из моих приложений где реализована нужная мне вещь.

    21 июня 2013 г. 11:50
  • А я настаиваю на использовании AppBar. Во-первых он не занимает место всегда и у вас больше места для контента. Во-вторых даже в нем уже что то есть, никто не мешает расширить его функционал и сделать подсветку текущего пункта так же не проблема.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    21 июня 2013 г. 12:22
  • У меня вопрос не по месту расположения меню, а по механизму его работы. Мне не разметка нужна, мне нужен код который сделает переключатель страниц. А его расположение может за время написание проекта еще измениться.
    21 июня 2013 г. 12:41
  • У меня вопрос не по месту расположения меню, а по механизму его работы.
    Так я вам механизм и подсказываю. Какой именно код вам подсказать? Просто пока по историисообщений складывается ощущения, что вы не определились с подходом вообще. AppBar это будет или просто фрейм внутри разметки? Нужно решится что делать, а потом делать.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    21 июня 2013 г. 12:46
  • А я настаиваю на использовании AppBar. Во-первых он не занимает место всегда и у вас больше места для контента. Во-вторых даже в нем уже что то есть, никто не мешает расширить его функционал и сделать подсветку текущего пункта так же не проблема.

    +1.

    Полное описание решения здесь.

    Здесь приведу выдержки. Добавляем в проект UserControl. С вот таким XAML:

    <UserControl
        x:Class="App3.MyMenu"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App3"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">    
        <ListView x:Name="lvMain">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <TextBlock>Главная</TextBlock>
            <TextBlock>Первая</TextBlock>
            <TextBlock>Вторая</TextBlock>
        </ListView>
    </UserControl>

    И вот таким кодом:

    public sealed partial class MyMenu : UserControl
    {
        public MyMenu()
        {
            this.InitializeComponent();
            Loaded += MyMenu_Loaded;
        }
    
        Type[] pages = { typeof(MainPage), typeof(BlankPage1), typeof(BlankPage2) };
    
        void MyMenu_Loaded(object sender, RoutedEventArgs e)
        {
            Page currentPage = GetCurrentPage();
            lvMain.SelectedIndex = pages.TakeWhile(p => p != currentPage.GetType()).Count();
            lvMain.SelectionChanged += lvMain_SelectionChanged;
        }
    
        void lvMain_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Page currentPage = GetCurrentPage();
            if (currentPage.GetType() != pages[lvMain.SelectedIndex])
            {
                currentPage.Frame.Navigate(pages[lvMain.SelectedIndex]);
            }
        }
    
        private Page GetCurrentPage()
        {
            FrameworkElement element = this;
            while (element != null && element.Parent != null && !(element.Parent is Page))
            {
                element = element.Parent as FrameworkElement;
            }
            Page currentPage = element.Parent as Page;
            return currentPage;
        }
    }

    На страницы добавляем наш контрол:

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" /> <!--Здесь будет меню-->
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <local:MyMenu />
        <TextBlock Grid.Row="1"  Text="Это главная страница" FontSize="20" />
    </Grid>

    Работает вот так:

    • Помечено в качестве ответа Ercheph 21 июня 2013 г. 13:03
    21 июня 2013 г. 12:55
    Отвечающий
  • Во! Это то что надо. Спасибо!
    21 июня 2013 г. 13:03