0

I think the question says it all: I want to build an Windows 8 Store app but how can I build an UI like this:

enter image description here

I think left is a normal ListView. The important thing is that I want an own AppBar for each ListViewEntry. And how can I load different pages (with different AppBars) in the right content area?

Cilenco
  • 6,951
  • 17
  • 72
  • 152

1 Answers1

1

You can put a ContentControl in the main panel and another one in the AppBar, then bind their Content properties to the SelectedItem property of the ListBox on the left and use ContentTemplateSelector to display the right UI for the selected page.

*EDIT - Sample

XAML

<Page
    x:Class="App17.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App17"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <local:PropertyPageTemplateSelector
            x:Key="PropertyPageTemplateSelector"/>
    </Page.Resources>
    <Grid
        Background="LemonChiffon">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition
                Width="2*" />
        </Grid.ColumnDefinitions>
        <ListBox
            x:Name="listBox"
            DisplayMemberPath="Label"/>
        <ContentControl
            Grid.Column="1"
            Content="{Binding SelectedItem, ElementName=listBox}"
            ContentTemplateSelector="{StaticResource PropertyPageTemplateSelector}">
            <ContentControl.Resources>
                <DataTemplate
                    x:Key="Options">
                    <StackPanel>
                        <TextBlock
                            Text="{Binding Label}"
                            FontSize="32"
                            Foreground="SlateGray" />
                        <Rectangle
                            Width="400"
                            Height="400"
                            Fill="Aquamarine" />
                    </StackPanel>
                </DataTemplate>
                <DataTemplate
                    x:Key="Preferences">
                    <StackPanel>
                        <TextBlock
                            Text="{Binding Label}"
                            FontSize="32"
                            Foreground="SlateGray" />
                        <Rectangle
                            Width="400"
                            Height="400"
                            Fill="Khaki" />
                    </StackPanel>
                </DataTemplate>
                <DataTemplate
                    x:Key="Properties">
                    <StackPanel>
                        <TextBlock
                            Text="{Binding Label}"
                            FontSize="32"
                            Foreground="SlateGray" />
                        <Rectangle
                            Width="400"
                            Height="400"
                            Fill="LawnGreen" />
                    </StackPanel>
                </DataTemplate>
                <DataTemplate
                    x:Key="Settings">
                    <StackPanel>
                        <TextBlock
                            Text="{Binding Label}"
                            FontSize="32"
                            Foreground="SlateGray" />
                        <Rectangle
                            Width="400"
                            Height="400"
                            Fill="Violet" />
                    </StackPanel>
                </DataTemplate>
            </ContentControl.Resources>
        </ContentControl>
    </Grid>
</Page>

C#

using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App17
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            listBox.ItemsSource =
                new List<PropertyPageViewModel>(
                    new PropertyPageViewModel[]
                    {
                        new OptionsPropertyPageViewModel(), 
                        new PreferencesPropertyPageViewModel(), 
                        new PropertiesPropertyPageViewModel(), 
                        new SettingsPropertyPageViewModel(), 
                    });
        }
    }

    public abstract class PropertyPageViewModel
    {
        public abstract string Label { get; }
    }

    public class OptionsPropertyPageViewModel : PropertyPageViewModel
    {
        public override string Label { get { return "Options"; } }
    }

    public class PreferencesPropertyPageViewModel : PropertyPageViewModel
    {
        public override string Label { get { return "Preferences"; } }
    }

    public class PropertiesPropertyPageViewModel : PropertyPageViewModel
    {
        public override string Label { get { return "Properties"; } }
    }

    public class SettingsPropertyPageViewModel : PropertyPageViewModel
    {
        public override string Label { get { return "Settings"; } }
    }

    public class PropertyPageTemplateSelector : DataTemplateSelector
    {
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            if (item == null) return base.SelectTemplateCore(item, container);

            var contentControl = (ContentControl)container;
            var viewModel = (PropertyPageViewModel)item;
            var templateKey = viewModel.Label;

            return (DataTemplate)contentControl.Resources[templateKey];
        }
    }
}
Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
  • What do you mean with _use ContentTemplateSelector to display the right UI for the selected page_? I have now a ContentControl and a second page _page2_. How can I load this page in the ContentControl? – Cilenco Apr 25 '13 at 19:22
  • Thank you that works great. But I have one more question. I can now load a page which has this Code `...`. Now I load it with `BlankPage1 bp = new BlankPage1(); return (DataTemplate)bp.Resources["Test"];`. I'm sure that can be done easier, right? I do not want to use `` in a page to load it. Can I load the whole page in an other way? Or do I have to add something to the `...`? – Cilenco Apr 26 '13 at 12:10
  • Not sure I understand what you mean. Can you ask a separate question and expand on your problem? – Filip Skakun Apr 26 '13 at 16:33
  • Here is my new question http://stackoverflow.com/questions/16241906/load-a-page-into-a-contentcontrol – Cilenco Apr 26 '13 at 17:19
  • Can you have a look on tis question? http://stackoverflow.com/questions/16252349/contentcontrol-does-not-change-the-content-function-never-called I tried to create a second ContentControl for the AppBar but there the content does not change... – Cilenco Apr 29 '13 at 14:53