UWP中用SplitView和Pivot实现两级目录
2015-12-24 20:52
465 查看
两级目录类似以下情况
20152015.1
内容1
内容2
内容3
内容x
12
12.1
内容1
内容2
内容3
12.2
内容1
内容2
24
24.1
内容1
内容2
24.2
内容1
内容2
内容3
24.3
内容1
内容2
SplitView控件:
有关SplitView的MS文档:SplitView class![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/16978b19452c8fc734c0851d34f8092a.png)
由图可以看出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代码
<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 classPivot控件有两个总要的部分: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
相关文章推荐
- NET IIS暴绝对路径漏洞
- NET LOCALGROUP命令详解(将用户添加到管理员组等)
- NET USER 命令详解(dos下添加用户)
- cpan安装Net::SSH::Perl中遇到的一些问题
- SQL 查询分析中使用net命令问题
- .Net 项目代码风格要求小结
- 用 Net 命令使局域网文件批量同步更新
- 浅析SQL语句行列转换的两种方法 case...when与pivot函数的应用
- 一步步教你读懂NET中IL(图文详解)
- 深入SQL中PIVOT 行列转换详解
- NET Runtime Optimization Service 1101 错误的解决方法
- C#.net数据库访问及其操作类
- NET::SMTP
- new 和 alloc init的区别
- System.Net.Mail with SSL to authenticate against port 465
- Win32_PingStatus vs [System.Net.NetworkInformation.Ping] vs Ping.exe
- 【STM32 .Net MF开发板学习-15】红外遥控智能小车
- NET命令
- IIS配置 NET 2.0 和1.1 服务器应用程序不可用
- FCKeditor 2.6.4在ASP.NET中的配置方法