[UWP] 制作一个可调整大小的 Splitview
一个非常简单的可调整大小的 SplitView
引言
距离我的上一篇技巧已经很久了,幸运的是,由于增加了 GridSplitter,上一篇技巧已经过时了,而这个 GridSplitter 是非常实用的,它包含在始终很有帮助的 Windows Community Toolkit 中。
这次,我决定通过提供一种从头开始实现拖拽行为的极其简单而智能的方法来弥补。
更具体地说,我将实现一种调整 SplitView
Pane 的大小的方法,我认为这可能是 Draggable
功能最实用的用途,而 GridSplitter
无法做到这一点。
考虑到实现的简单性,这篇文章会相对较长,因为我为其添加了介绍/教育性的内容,所以如果你是那种喜欢示例代码的人,可以直接查看 GitHub 仓库。
背景
您将需要:
- 安装了 UWP 开发工具包的 Visual Studio 2017 和最新 SDK 版本
- 知道如何编写几行代码
实现
设置
首先,我们创建一个新的 UWP 项目,并将解决方案命名为“DragSplitView
”。
等待它加载,然后打开 MainPage.xaml。
现在我们将开始构建设计的骨架,我们将页面中的主 Grid
命名为 MasterGrid
,并为其添加以下 RowDefinitions
:
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
在第一行,我们分配一个 ToggleButton
,并称之为“OpenButton
”,我们将 IsChecked="True"
IsChecked="True"
,我们在其中分配一个图标:<SymbolIcon Symbol="More" />
在第二行,我们将分配一个新的 SplitView
,称之为“CoreSplitView
”,并将 DisplayMode
设置为“Inline
”。
有关 Grid 和 Placement Definitions 的更多信息,请参阅下面的附录。
最终结果应该看起来像这样
<Page
x:Class="DragSplitView.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:DragSplitView"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid Name="MasterGrid">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<ToggleButton Name="OpenButton" IsChecked="True">
<SymbolIcon Symbol="More" />
</ToggleButton>
<SplitView Name="CoreSplitView"
Grid.Row="1"
DisplayMode="Inline">
</SplitView>
</Grid>
</Page>
基本绑定
现在是时候实现我们 App 的基本交互性了,为此,我们将使用 Binding 系统,如果您不熟悉 Binding 并想了解更多,请查看这个 链接。
我们将控制我们 SplitView
Pane 的打开状态,换句话说,我们 ToggleButton
的选中状态将反映我们 SplitView
的状态,这很容易通过 Binding 来实现。
我们将以下内容添加到我们的 SplitView
Properties 中
IsPaneOpen="{Binding IsChecked,ElementName=OpenButton}"
OpenPaneLength="400"
您现在可以运行程序,看看按钮如何控制状态,请注意 ElementName
指的是我们的 ToggleButton
,而 IsChecked
指的是该 ToggleButton
中的相关属性。
收尾
我们将最终确定 UI 布局,以便进入最后阶段。
我们继续打开 <SplitView.Pane>
并添加一个名为“PaneGrid
”的 Grid
,并将其 Background
设置为“Gold
”,这个 Grid
本身将托管以下新控件
<Slider Name="MasterSlider"
MinWidth="480"
VerticalAlignment="Stretch"
Maximum="480"
Minimum="20"
Opacity="0"
Value="150" />
这是一个 Slider 控件,它有一个核心目的,稍后我们将深入探讨。
在这个 Slider 下方,我们添加这个
<StackPanel
Name="PaneStackPanel"
Margin="0,0,20,0"
Background="MediumAquamarine">
<TextBlock TextWrapping="Wrap" Text="this is a custom draggable implementation that is pretty cool,
for more stuff check me out at www.codeproject.com/Members/Georgemns" />
</StackPanel>
在 </SplitView.Pane>
下方,我们将添加一个名为“ContentGrid
”的 Grid
,并将其 Background
设置为“LightSteelBlue
”。
最后,但同样重要的是,更改
OpenPaneLength="400"
to
OpenPaneLength="{Binding Value, ElementName=MasterSlider, Mode=OneWay}"
正如您可能猜到的,Value
是我们 Slider 的当前进度,通过这个语句,它将以 OneWay 模式“连接”到 OpenPaneLength。
到此为止,您需要做的就这些了,如果您一直跟着操作,文档应该看起来是这样的
<Page x:Class="DragSplitView.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:DragSplitView"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid Name="MasterGrid">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<ToggleButton Name="OpenButton" IsChecked="True">
<SymbolIcon Symbol="More" />
</ToggleButton>
<SplitView Name="CoreSplitView"
Grid.Row="1"
DisplayMode="Inline"
IsPaneOpen="{Binding IsChecked,ElementName=OpenButton}"
OpenPaneLength="{Binding Value, ElementName=MasterSlider, Mode=OneWay}" >
<SplitView.Pane>
<Grid Name="PaneGrid" Background="Gold">
<Slider Name="MasterSlider"
MinWidth="480"
VerticalAlignment="Stretch"
Maximum="480"
Minimum="20"
Opacity="0"
Value="150" />
<StackPanel Name="PaneStackPanel"
Margin="0,0,20,0" Background="MediumAquamarine">
<TextBlock TextWrapping="Wrap" Text="this is a custom draggable implementation
that is pretty cool, for more stuff check me out
at www.codeproject.com/Members/Georgemns" />
</StackPanel>
</Grid>
</SplitView.Pane>
<Grid Name="ContentGrid" Background="LightSteelBlue">
</Grid>
</SplitView>
</Grid>
</Page>
剖析
正如我所说,Slider 是这个系统的核心,Slider 的当前进度 (Value
) 直接反映在 Pane 的当前宽度上,通过上面展示的 Binding 表达式,就像我们用那个按钮实现的打开-关闭功能一样。
现在更具体地说
- 我们为 Slider 分配了
MinWidth="480"
,Maximum="480"
和Minimum="20"
,因为否则 Slider 会改变宽度并“压缩”,从而丢失我们所需的 1-1 像素到进度的对应关系,480 只是我们选择的一个任意数字,作为我们 Pane 可以扩展到的最大潜在宽度,同样,Minimum 是 Pane 的最小宽度,值得注意的是,您应该选择一个小于 500 的最大值,因为这是默认的最小窗口大小。 - 我们还将
Value="150"
设置为 App 启动时的起点,您可以选择扩展此实现,保存当前值,然后在 App 再次启动时加载回来。 VerticalAlignment =”Stretch”
,这使得 Slider 可以覆盖整个垂直空间,换句话说,Slider 不再像一条细细的彩色条,而是整个区域,可以响应 Pane 内的任何用户输入。Opacity="0"
,这是使某物变得不可见的智能方法,请注意,我们没有使用实际的Visibility
属性,因为降低不透明度仍然允许我们与该条进行交互,即使您实际上看不到它。
直接位于 Slider 下方的 StackPanel
,充当了我们 Slider 的覆盖层。请注意,它具有 Margin="0,0,20,0"
,这意味着距离右壁有 20px 的距离,这使得 Slider 区域可以暴露为一个金色的条,用于拖动 Pane,同样,20px 是一个任意数字,但它必须与 Slider 的 Minimum 相匹配。
历史
- 2018 年 9 月 27 日:发布