兩級目錄類似以下情況
- 2015
- 2015.1
- 内容1
- 内容2
- 内容3
- 内容x
- 2015.1
- 12
- 12.1
- 内容1
- 内容2
- 内容3
- 12.2
- 内容1
- 内容2
- 12.1
- 24
- 24.1
- 内容1
- 内容2
- 24.2
- 内容1
- 内容2
- 内容3
- 24.3
- 内容1
- 内容2
- 24.1
SplitView控件:
有關SplitView的MS文檔:SplitView class

由圖可以看出SplitView控件由Pane和Content組成,是以Pane可以用來存放一級目錄,而Content可以用來存放二級目錄以及二級目錄下的内容。
SplitView控件有幾個重要的屬性:
Property | Access type | Description |
---|---|---|
DisplayMode | Read/write | Gets of sets a value that specifies how the pane and content areas of a SplitView are shown. |
OpenPaneLength | Read/write | Gets or sets the width of the SplitView pane when it’s fully expanded. |
IsPaneOpen | Read/write | Gets or sets a value that specifies whether the SplitView pane is expanded to its full width. |
使用SplitView可以實作UWP上新加入的漢堡包菜單
初始界面
點選右下角菜單按鈕後
SplitView代碼
<SplitView x:Name="spViewRoot"
DisplayMode="Overlay"
OpenPaneLength="256"
IsPaneOpen="{Binding MenuOpened, Mode=TwoWay}"
IsTabStop="False">
<SplitView.Pane>
<Grid>
</Grid>
</SplitView.Pane>
<SplitView.Content>
<Grid>
</Grid>
</SplitView.Content>
</SplitView>
Splitview的IsPaneOpen決定了Pane是否展開他綁定了一個背景資料:MenuOpened.
private bool menuOpened;
public bool MenuOpened
{
get
{
return menuOpened;
}
set
{
menuOpened = value;
OnPropertyChanged("MenuOpened");
}
}
配合的BottomAppBar代碼
<Page.BottomAppBar>
<CommandBar x:Name="btmCmdBar">
<AppBarButton Label="Menu"
Click="AppBarButton_Click">
<AppBarButton.Icon>
<FontIcon Glyph=""/>
</AppBarButton.Icon>
</AppBarButton>
</CommandBar>
</Page.BottomAppBar>
AppBarButton的Click事件裡要做的就是對SplitView的IsPaneOpen取反。這樣,每次點選菜單按鈕就可以讓菜單打開或關閉。
接下來要做的就是向SplitView中添加一級目錄
一級目錄就相當于是一個清單,是以隻需要在SplitView的Pane中添加一個ListView即可,當然為了美觀我稍微的設計了一下布局
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListView Grid.Row="1"
Grid.ColumnSpan="2"
ItemsSource="{Binding NavList}"
ItemTemplate="{StaticResource MenuListItemTemplate}">
</ListView>
</Grid>
ListView中的元素布局模闆全用資料綁定實作:
<Page.Resources>
<DataTemplate x:Key="MenuListItemTemplate"
x:DataType="model:NavItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<FontIcon x:Name="Glyph" FontSize="16" Glyph="{x:Bind SymbolAsChar}" VerticalAlignment="Center" HorizontalAlignment="Center" ToolTipService.ToolTip="{x:Bind Label}"/>
<TextBlock x:Name="Text" Grid.Column="1" Text="{x:Bind Label}" />
</Grid>
</DataTemplate>
<vm:MainPageViewModel x:Key="viewModel"/>
</Page.Resources>
每個菜單元素的Model:
public class NavItem
{
public enum NavType
{
one,
two,
three,
}
public string Label { get; set; }
//用于表示目錄名稱前的小圖示
public Symbol Symbol { get; set; }
public char SymbolAsChar
{
get
{
return (char)this.Symbol;
}
}
//用來辨別目錄是哪一項
public NavType DestPage { get; set; }
public object Arguments { get; set; }
}
ViewModel代碼如下:
//用于前台一級目錄中的 ListView 資料綁定
private List<NavItem> navList;
public List<NavItem> NavList
{
get
{
return navList;
}
set
{
navList = value;
}
}
//在 ViewModel 的構造函數中初始化 ListView 的資料
public MainPageViewModel()
{
this.NavList = new List<NavItem>(
new[]
{
new NavItem()
{
Symbol = Symbol.Favorite,
Label = "2015",
DestPage = NavItem.NavType.one,
},
new NavItem()
{
Symbol = Symbol.Favorite,
Label = "12",
DestPage = NavItem.NavType.two,
},
new NavItem()
{
Symbol = Symbol.Favorite,
Label = "24",
DestPage = NavItem.NavType.three,
},
});
}
此時運作程式就得到了我想要的效果:
更多關于SplitView和漢堡包菜單的實作請看MS官方提供的例子:
Windows-universal-samples / Samples / XamlNavigation /
GitHub
接下來就是二級目錄和二級目錄下内容的呈現了。
Pivot控件
有關Pivot的MS文檔:Pivot class
Pivot控件有兩個總要的部分:Title和Items。
Title就是顯示在Pivot頂部的标題;Items就是Pivot中的内容,也相當于是一個清單。
而每個Pivot的Item又由兩部分組成:Header和Item,是以我從内到外設計模闆。
使用模闆和資料綁定的好處就是可以動态加載Pivot,這樣我們不用把Pivot的數量定死,而是根據一級目錄下的元素個數來添加Pivot。
每個PivotItem的模闆:
每個PivotItem中用一個ListView來展示内容
<DataTemplate x:Key="PivotListTemplate">
<ListView ItemTemplate="{StaticResource PivotListItemTemplate}"
ItemsSource="{Binding ContentList}"/>
</DataTemplate>
<DataTemplate x:Key="PivotListItemTemplate">
<TextBlock Text="{Binding Content}"/>
</DataTemplate>
他隻有一個TextBlock用來顯示每一個元素中的内容。
每個PivotItem的header模闆:
<DataTemplate x:Key="PivotHeaderTemplate">
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
他隻有一個TextBlock用來顯示每一個元素Header中的内容。
Pivot代碼
<Pivot ItemTemplate="{StaticResource PivotListTemplate}"
HeaderTemplate="{StaticResource PiovtHeaderTemplate}"
ItemsSource="{Binding PivotList}"
Title="{Binding PivotTitle}">
</Pivot>
整個資料綁定的結構:
此時運作結果:
接下來要實作的就是通過SplitView的Pane中菜單點選不同的一級目錄,然後再SplitView的Content中顯示擁有不同數量PivotItem的Pivot。
為了達到以上效果,我們需要改進一下SplitView的Pane中的ListView。
首先需要讓ListView實作元素點選事件,由于ListView沒有Command,是以我們需要用微軟提供的一個方法來實作。
首先添加引用
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
然後在ListView中添加如下代碼:
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SelectionChanged">
<core:InvokeCommandAction Command="{Binding NavCommand}" CommandParameter="{Binding ElementName=lvNavMenu, Path=SelectedItem}"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
這樣我們就将背景的NavCommand綁定到了ListView的SelectionChanged事件。
背景ViewModel中NavCommand代碼:
private DelegateCommand navCommand;
public DelegateCommand NavCommand
{
get
{
return navCommand ?? (navCommand = new DelegateCommand(
(Object obj) =>
{
NavItem selectedItem = obj as NavItem;
if (selectedItem != null)
{
this.PivotTitle = selectedItem.Label;
//判斷目前選擇的是哪一個一級目錄,根據不同的選擇加載不同的PivotList
switch (selectedItem.DestPage)
{
case NavItem.NavType.one:
this.PivotList = new List<MyPivotItem>() { new MyPivotItem() };
break;
case NavItem.NavType.two:
this.PivotList = new List<MyPivotItem>() { new MyPivotItem(), new MyPivotItem() };
break;
case NavItem.NavType.three:
this.PivotList = new List<MyPivotItem>() { new MyPivotItem(), new MyPivotItem(), new MyPivotItem() };
break;
}
this.MenuOpened = false;
}
},
(Object obj) => true));
}
}
結果如下所示
更多有關Pivot 的内容請看微軟官方的GitHub例子:
Windows-universal-samples / Samples / XamlPivot /
GitHub
本人所用Demo源碼:GitHub