扩展器
使用扩展器控件,可以显示或隐藏与一段始终可见的主要内容相关的重要内容。 标头中包含的项始终可见。 用户可以通过与标头交互,展开和折叠显示次要内容的内容区域。 内容区域展开后,会使其他 UI 元素跳出;它不会覆盖其他 UI。 Expander
可以向上或向下展开。
Header
和 Content
区域均可包含从简单文本到复杂 UI 布局的任何内容。 例如,可以使用控件显示项的其他选项。
这是正确的控件吗?
如果某些主要内容应始终可见,但相关的次要内容可能在需要之前都处于隐藏状态,则使用 Expander
。 显示空间有限并且信息或选项可以组合在一起时,通常使用此 UI。 在有需要之前隐藏次要内容还有助于将用户的注意力放在应用最重要的部分。
UWP 和 WinUI 2
重要
本文中的信息和示例是针对使用 Windows App SDK 和 WinUI 3 的应用优化的,但通常适用于使用 WinUI 2 的 UWP 应用。 有关特定于平台的信息和示例,请查看 UWP API 参考。
本部分包含在 UWP 或 WinUI 2 应用中使用该控件所需的信息。
用于 UWP 应用的 Expander 需要 WinUI 2。 有关详细信息(包括安装说明),请参阅 WinUI 2。 此控件的 API 存在于 Microsoft.UI.Xaml.Controls 命名空间中。
- WinUI 2 API:Expander 类、标头属性、Content 属性
- 打开 WinUI 2 库应用,了解 Expander 的实际应用。 WinUI 2 库应用包括大多数 WinUI 2 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码。
要将本文中的代码与 WinUI 2 配合使用,请使用 XAML 中的别名(我们使用 muxc
)来表示项目中包含的 Windows UI 库 API。 有关详细信息,请参阅 WinUI 2 入门。
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:Expander />
创建扩展器
- 重要 API:Expander 类、Header 属性、Content 属性
WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码
本示例演示如何使用默认样式创建简单的扩展器。 标头属性定义始终可见的元素。 内容属性定义可以折叠和展开的元素。 此示例创建与上图类似的 Expander
。
<Expander Header="This text is in the header"
Content="This is in the content"/>
扩展器内容
Expander
的内容属性可以是任何类型的对象,但通常为字符串或 UIElement。 有关设置 Content
属性的更多详细信息,请参阅 ContentControl 类的“备注”部分。
可以使用复杂的交互式 UI 作为 Expander
的内容,包括父级 Expander
内容中嵌套的 Expander
控件,如下所示。
内容对齐
可以通过设置 Expander
控件上的 HorizontalContentAlignment 和 VerticalContentAlignment 属性来对齐内容。 设置这些属性时,对齐方式仅适用于扩展的内容,而不适用于标题。
控制扩展器的大小
默认情况下,标头和内容区域会自动调整大小以适应其内容。 务必使用正确的方法来控制 Expander
的大小,以避免不良的外观或行为。
宽度
如果内容的宽度大于标题,则在展开时,标题宽度将增加以与内容区域匹配,并在内容区域折叠时缩小。 要防止控件宽度在展开或折叠时更改,可以设置显式宽度;如果控件是面板的子控件,则将 HorizontalAlignment 设置为“拉伸”,并让布局面板控制大小。
在这里,一系列相关的 Expander
控件放置在 StackPanel 中。 其中HorizontalAlignment
每个Expander
元素StackPanel
都设置为Stretch
使用资源中的StackPanel
样式,并且控件的宽度StackPanel
决定了控件的Expander
宽度。
<StackPanel x:Name="ExpanderStack" MaxWidth="600">
<StackPanel.Resources>
<Style TargetType="Expander">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</StackPanel.Resources>
<Expander Header="Choose your crust"> ... </Expander>
<Expander Header="Choose your sauce"> ... </Expander>
<Expander Header="Choose your toppings"> ... </Expander>
</StackPanel>
Height
不要在 Expander
上指定高度。 如果执行此操作,即使内容区域处于折叠状态,控件也会保留该空间,这会破坏 Expander
的用途。 要指定展开内容区域的大小,请设置 Expander
的内容的大小维度。 如果需要,可以限制内容的 Height
,并使内容可滚动。
可滚动内容
如果内容对于内容区域来说太大,可以将内容包装为 ScrollViewer,使内容区域可滚动。 Expander
控件不自动提供滚动功能。
在 Expander
内容中放置 ScrollViewer
时,请将 ScrollViewer
控件的高度设置为内容区域所需的高度。 如果改为对 ScrollViewer
中的内容设置高度维度,则 ScrollViewer
不会识别此设置,因此不会提供可滚动内容。
下面的示例演示如何创建一个 Expander
控件,该控件包含可滚动文本作为其内容。
<Expander Header="Expander with scrollable content">
<ScrollViewer MaxHeight="200">
<Grid>
<TextBlock TextWrapping="Wrap">
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</TextBlock>
</Grid>
</ScrollViewer>
</Expander>
展开和折叠内容区域
默认情况下,扩展器处于折叠状态,可以向下展开。
- 将 IsExpanded 属性设置为
true
可使内容区域最初处于展开状态。 - 将 ExpandDirection 属性设置为 向上 可使内容向上展开。
<Expander IsExpanded="True" ExpandDirection="Up">
通过设置IsExpanded
属性或与Header
属互,以编程方式展开或折叠一个 Expander
;它不能被轻消除。
提示
单击或点击暂时性 UI(例如 Flyout
或 ComboBox
的开放式下拉菜单)的外部时,它会关闭。 这称为轻型消除。 Expander
的内容区域不被视为是暂时性的,并且不会覆盖其他 UI,因此它不支持轻型消除。
还可以处理展开和折叠事件,以便在显示或隐藏内容时执行操作。 下面是这些事件的一些示例。
展开事件
本示例中你有一组扩展器,并且只希望一次打开其中一个。 用户打开 Expander
时,将处理展开事件,并折叠组中除用户单击的控件以外的所有 Expander
控件。
注意
取决于应用和用户体验,在用户展开其他控件时,可能会自动折叠 Expander
控件。 但是,这也会使用户失去控制权。 如果此行为可能会很有用,请考虑使其成为用户可以轻松设置的选项。
<StackPanel x:Name="ExpanderStack">
<Expander Header="Choose your crust"
Expanding="Expander_Expanding"> ... </Expander>
<Expander Header="Choose your sauce"
Expanding="Expander_Expanding"> ... </Expander>
<Expander Header="Choose your toppings"
Expanding="Expander_Expanding"> ... </Expander>
</StackPanel>
// Let the user opt out of custom behavior.
private bool _autoCollapse = true;
private void Expander_Expanding(muxc.Expander sender,
muxc.ExpanderExpandingEventArgs args)
{
if (_autoCollapse == true)
{
foreach (muxc.Expander ex in ExpanderStack.Children)
{
if (ex != sender && ex.IsExpanded)
ex.IsExpanded = false;
}
}
}
折叠事件
本示例中,你将处理折叠事件,并使用在 Content
中选择的选项概述填充 Header
。
此图显示 Expander
的内容已展开并选择了选项。
折叠后,所选选项将在标头中汇总,因此用户仍可以在不打开 Expander
的情况下查看它们。
<Expander IsExpanded="True"
Expanding="Expander_Expanding"
Collapsed="Expander_Collapsed">
<Expander.Header>
<Grid>
<TextBlock Text="Choose your crust"/>
<TextBlock x:Name="tbCrustSelections"
HorizontalAlignment="Right"
Style="{StaticResource CaptionTextBlockStyle}"/>
</Grid>
</Expander.Header>
<StackPanel Orientation="Horizontal">
<RadioButtons x:Name="rbCrustType" SelectedIndex="0">
<x:String>Classic</x:String>
<x:String>Whole wheat</x:String>
<x:String>Gluten free</x:String>
</RadioButtons>
<RadioButtons x:Name="rbCrustStyle" SelectedIndex="0"
Margin="48,0,0,0">
<x:String>Regular</x:String>
<x:String>Thin</x:String>
<x:String>Pan</x:String>
<x:String>Stuffed</x:String>
</RadioButtons>
</StackPanel>
</Expander>
private void Expander_Collapsed(muxc.Expander sender,
muxc.ExpanderCollapsedEventArgs args)
{
// Update the header with options selected in the content.
tbCrustSelections.Text = rbCrustType.SelectedItem.ToString() +
", " + rbCrustStyle.SelectedItem.ToString();
}
轻型样式
可以修改默认 Style
和 ControlTemplate
以使控件具有唯一的外观。 请参阅扩展器 API 文档的“控件样式和模板”部分,查看可用主题资源的列表。 有关详细信息,请参阅设置控件样式一文中的轻量级样式设置部分。
建议
- 在显示空间有限时使用
Expander
,可能会导致某些次要内容在用户请求它之前处于隐藏状态。
代码示例
此 XAML 创建本文中其他部分所示的 Expander
控件组。 Expanding
和 Collapsed
事件处理程序的代码也显示在前面的部分中。
<StackPanel x:Name="ExpanderStack" MaxWidth="600">
<StackPanel.Resources>
<Style TargetType="Expander">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</StackPanel.Resources>
<Expander IsExpanded="True"
Expanding="Expander_Expanding"
Collapsed="Expander_Collapsed">
<Expander.Header>
<Grid>
<TextBlock Text="Choose your crust"/>
<TextBlock x:Name="tbCrustSelections"
HorizontalAlignment="Right"
Style="{StaticResource CaptionTextBlockStyle}"/>
</Grid>
</Expander.Header>
<StackPanel Orientation="Horizontal">
<RadioButtons x:Name="rbCrustType" SelectedIndex="0">
<x:String>Classic</x:String>
<x:String>Whole wheat</x:String>
<x:String>Gluten free</x:String>
</RadioButtons>
<RadioButtons x:Name="rbCrustStyle" SelectedIndex="0"
Margin="48,0,0,0">
<x:String>Regular</x:String>
<x:String>Thin</x:String>
<x:String>Pan</x:String>
<x:String>Stuffed</x:String>
</RadioButtons>
</StackPanel>
</Expander>
<Expander Header="Choose your sauce" Margin="24"
Expanding="Expander_Expanding">
<RadioButtons SelectedIndex="0" MaxColumns="2">
<x:String>Classic red</x:String>
<x:String>Garlic</x:String>
<x:String>Pesto</x:String>
<x:String>Barbecue</x:String>
</RadioButtons>
</Expander>
<Expander Header="Choose your toppings"
Expanding="Expander_Expanding">
<StackPanel>
<Expander>
<Expander.Header>
<RadioButton GroupName="Toppings" Content="House special"/>
</Expander.Header>
<TextBlock Text="Cheese, pepperoni, sausage, black olives, mushrooms"
TextWrapping="WrapWholeWords"/>
</Expander>
<Expander>
<Expander.Header>
<RadioButton GroupName="Toppings" Content="Vegetarian"/>
</Expander.Header>
<TextBlock Text="Cheese, mushrooms, black olives, green peppers, artichoke hearts"
TextWrapping="WrapWholeWords"/>
</Expander>
<Expander>
<Expander.Header>
<RadioButton GroupName="Toppings" Content="All meat"/>
</Expander.Header>
<TextBlock Text="Cheese, pepperoni, sausage, ground beef, salami"
TextWrapping="WrapWholeWords"/>
</Expander>
<Expander>
<Expander.Header>
<RadioButton GroupName="Toppings" Content="Choose your own"/>
</Expander.Header>
<StackPanel Orientation="Horizontal">
<StackPanel>
<CheckBox Content="Cheese"/>
<CheckBox Content="Pepperoni"/>
<CheckBox Content="Sausage"/>
</StackPanel>
<StackPanel>
<CheckBox Content="Ground beef"/>
<CheckBox Content="Salami"/>
<CheckBox Content="Mushroom"/>
</StackPanel>
<StackPanel>
<CheckBox Content="Black olives"/>
<CheckBox Content="Green peppers"/>
<CheckBox Content="Artichoke hearts"/>
</StackPanel>
</StackPanel>
</Expander>
</StackPanel>
</Expander>
</StackPanel>