跨平台WPF框架Avalonia教程 十六

SelectableTextBlock 可选文本块

SelectableTextBlock 块是一个用于显示文本的标签,允许选择和复制文本。它可以显示多行,并且可以完全控制所使用的字体。

有用的属性

您可能最常使用这些属性:

属性 描述
SelectionStart 当前选择的起始字符索引。
SelectionEnd 当前选择的结束字符索引。
SelectionBrush 高亮显示选中文本的画刷。
SelectionForeground 用于选中文本前景的画刷。
FontSize 字体的大小。
FontWeight 字体的粗细。默认是正常,选项包括 Bold
FontStyle 应用于字母的样式。默认是正常,选项包括 Italic
TextDecorations 应用于字母的线条装饰。默认是无,选项包括 UnderlineStrikethroughBaselineOverline。要同时应用多个,请在选项之间用空格分隔。
xml:space TextBlock 本身会尊重其内容在 XAML 中设置的换行和空白,但如果没有 xml:space="preserve",它将被解析器过滤掉。

示例

此示例显示了用作标题、单行和多行显示的文本块。

  <StackPanel Margin="20">
  <SelectableTextBlock Margin="0 5" FontSize="18" FontWeight="Bold" >Heading</SelectableTextBlock>
  <SelectableTextBlock Margin="0 5" FontStyle="Italic" xml:space="preserve" SelectionBrush="Red">This is a single line.</SelectableTextBlock>
  <SelectableTextBlock Margin="0 5" xml:space="preserve" SelectionStart="3" SelectionEnd="13">This is a multi-line display
    that has returns in it.
    The text block respects the line breaks
    as set out in XAML.</SelectableTextBlock>
</StackPanel>

样式在预览窗格中有效:

Slider 滑块

滑块控件通过沿轨道长度移动滑块按钮的相对位置来展示其数值。位置是相对于最大值和最小值而定的。

在滑块按钮上进行拖动交互可以改变值,使其在最大值和最小值之间变动。键盘和点击交互也可以微调数值。

常用属性

你可能最常使用这些属性:

属性 描述
Maximum 设置最大值。
Minimum 设置最小值。

示例

在此示例中,滑块的值将显示在下方的文本块中,通过绑定到一个控件实现。

信息

要了解如何将一个控件绑定到另一个控件,请参阅这里的指南。

这里的最大值和最小值是默认的(分别为0和100)。

<StackPanel Margin="20">
  <TextBlock Text="{Binding #slider.Value}" 
              HorizontalAlignment="Center"/>
  <Slider x:Name="slider" />
</StackPanel>

在Windows上,滑块看起来是这样的:

SplitView 分屏视图

分屏视图提供一个包含两个部分的容器:主内容区和侧边面板。主内容区始终可见。面板可以展开和折叠。折叠的面板可以完全隐藏,或留出稍微打开的空间------例如,有足够的空间放置一些图标按钮。

常用属性

你可能最常使用这些属性:

属性 描述
PanePlacement 设置面板的位置(左或右)。
IsPaneOpen 布尔值,默认为真。面板是否处于打开状态?
DisplayMode 控制面板在打开和关闭状态下的显示方式。请看下文。
OpenPaneLength 定义面板打开时的宽度。
CompactPaneLength 定义面板关闭且显示模式为紧凑时的宽度。

显示模式属性控制面板在其打开和关闭状态下的绘制方式。有四个选项:

  • 覆盖

    面板完全隐藏,直到被打开。打开时,面板会覆盖内容区域。

  • 内联

    面板始终可见,宽度固定,不会覆盖内容区域。面板和内容区域分割可用的屏幕空间,但如果容器宽度变化,调整的是内容区域的大小。

  • 紧凑覆盖

    在此模式下,面板的窄部分始终可见,宽度足以显示图标。默认的关闭面板宽度为48px,可以通过CompactPaneLength属性值修改。如果面板被打开,它将覆盖内容区域。

  • 紧凑内联

    在此模式下,面板的窄部分始终可见,宽度足以显示图标。默认的关闭面板宽度为48px,可以通过CompactPaneLength属性值修改。如果面板被打开,它将减小内容区域的大小。

示例

<SplitView IsPaneOpen="True"
           DisplayMode="Inline"
           OpenPaneLength="300">
    <SplitView.Pane>
        <TextBlock Text="Pane"
                   FontSize="24"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"/>
    </SplitView.Pane>

    <Grid>
        <TextBlock Text="Content"
                   FontSize="24"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"/>
    </Grid>
</SplitView>

控件在Windows上运行时的样子如下:

紧凑显示模式

你可以使用MVVM模式与分屏视图控件和某个紧凑显示模式设置一起,实现一个"工具面板"样式的用户界面。当面板关闭时,有足够的空间显示一个打开面板的图标按钮。

StackPanel 堆栈面板

堆栈面板通过水平或垂直堆叠其子控件来排列它们。堆栈面板通常用于在页面上排列UI的一个小部分。

在堆栈面板内部,如果子控件在垂直于堆栈的方向上没有设置大小属性,那么子控件将扩展以填充可用空间。例如,在水平方向上,如果未设置,子控件的高度将会扩展。

在堆栈的方向上,堆栈面板将总是扩展以适应所有子控件。

常用属性

你可能最常使用这些属性:

属性 描述
Orientation 设置堆栈的方向。可选择水平或垂直(默认)。
Spacing 在子控件之间创建均匀间距。

示例

以下XAML展示了如何创建一个垂直的堆栈面板。

<StackPanel Width="200">
    <Rectangle Fill="Red" Height="50"/>
    <Rectangle Fill="Blue" Height="50"/>
    <Rectangle Fill="Green" Height="100"/>
    <Rectangle Fill="Orange" Height="50"/>
</StackPanel>

结果显示子控件被拉伸以适应宽度,而堆栈面板的总高度等于子控件高度的总和。

TabControl 选项卡控件

TabControl 允许您将视图细分为选项卡项。

每个选项卡项都有一个标题和一个内容区。标题按它们在 XAML 中出现的顺序呈现在一个条带中。当用户点击选项卡标题时,其内容变得可见,并放置在选项卡控件的内容区中,位于选项卡条带下方。

您可以在标题和内容区中组合 UI,以满足 Avalonia UI 应用程序的 UI 要求。

信息

如果您只需要此控件的选项卡标题部分的功能,请考虑使用选项卡条带。请参见这里

示例

这是一个简单的选项卡示例。选项卡内容只是一些文本:

<TabControl Margin="5">
  <TabItem Header="Tab 1">
    <TextBlock Margin="5">This is tab 1 content</TextBlock>
  </TabItem>
  <TabItem Header="Tab 2">
    <TextBlock Margin="5">This is tab 2 content</TextBlock>
  </TabItem>
  <TabItem Header="Tab 3">
    <TextBlock Margin="5">This is tab 3 content</TextBlock>
  </TabItem>
</TabControl>

选项卡控件甚至可以在预览窗格中工作!

TabStrip 选项卡头条带

显示一条选项卡头的条带。您可以将此控件用作水平菜单。

选项卡条由 <TabItem> 元素组成。这些元素按它们在 XAML 中出现的顺序显示。

有用的属性

您可能最常使用此属性:

属性 描述
TabItem.Header 选项卡的文本。

示例

<TabStrip Margin="5">
  <TabItem Header="Tab 1"/>
  <TabItem Header="Tab 2"/>
  <TabItem Header="Tab 3"/>
</TabStrip>

在 Windows 上运行时,它看起来像这样:

TextBlock 文本块

TextBlock 是一个用于显示文本的只读标签。它可以显示多行文本,并且可以完全控制所使用的字体。

常用属性

你可能最常使用这些属性:

属性 描述
Text 要显示的文本。
FontSize 字体的大小。
FontWeight 字体的粗细。默认是正常,选项包括 Bold
FontStyle 应用于字母的样式。默认是正常,选项包括 Italic
TextDecorations 应用于字母的线条装饰。默认是无,选项包括 UnderlineStrikethroughBaselineOverline。要同时应用多个,请在选项之间用空格分隔。
xml:space xml:space="preserve" 指示 XML 解析器保留分配给 TextBlock 的内容的换行符和空白,否则默认情况下会被删除。

示例

此示例演示使用多个 TextBlock 控件来显示标题、包含额外空格的单行和多行显示。

<StackPanel Margin="20">
    <TextBlock Margin="0 5" FontSize="18" FontWeight="Bold">Heading</TextBlock>
    <TextBlock Margin="0 5" FontStyle="Italic" xml:space="preserve">This is  a single line.</TextBlock>
    <TextBlock Margin="0 5" xml:space="preserve">This is a multi-line display
that has returns in it.
The text block respects the line breaks
as set out in XAML.</TextBlock>
</StackPanel>

样式在预览窗格中工作:

内联

文本内联允许在单个 TextBlock 内对文本和控件进行多样化格式化。虽然 TextBlock.Text 通常用于显示单一格式的文本,但其子 Content 允许包含内联集合。

Run

Run 内联表示一段连续的统一格式文本。

<Style Selector="Run.activity">
    <Setter Property="Foreground" Value="#C469EE" />
    <Setter Property="FontStyle" Value="Italic" />
    <Setter Property="TextDecorations" Value="Underline" />
</Style>

<TextBlock>
    <Run Text="Your name is" />
    <Run FontSize="24" FontWeight="Bold" Foreground="Orange" Text="{Binding Name}" />
    <Run Text="and your favorite activity is" />
    <Run Classes="activity" Text="{Binding Activity}" />
</TextBlock>

LineBreak

LineBreak 内联强制换行。

<TextBlock>
        This is the first line and<LineBreak />here comes the second
</TextBlock>

Span

Span 内联允许对内联进行分组,包括非文本内联。虽然 Span 可以应用自己的文本格式,但有一些预定义的格式内联派生自 SpanBoldItalicUnderline。用户还可以从 Span 派生以创建自己的格式,而不是使用样式。

<TextBlock>
    This text is <Span Foreground="Green"> green with <Bold>bold sections,</Bold>
    <Italic>italic <Span Foreground="Red">red</Span> sections,</Italic>
    some
    <Run FontSize="24"> enlarged font runs,</Run>
    and</Span>
    back to the original formatting
</TextBlock>

InlineUIContainer

InlineUIContainer 允许将任何 Control 作为内联包含。

<TextBlock ClipToBounds="False" FontSize="32" TextWrapping="Wrap">
        🚀 This <Span BaselineAlignment="TextTop">example</Span> shows the <Bold>power</Bold> of
        <InlineUIContainer BaselineAlignment="Baseline">
                <Image Width="32" Height="32" VerticalAlignment="Top" Source="/Assets/avalonia-logo.ico" />
        </InlineUIContainer>
        in creating rich text displays with
        <InlineUIContainer>
                <Button Padding="0,8,0,0">
                        <TextBlock ClipToBounds="False" FontSize="24" Text="👍👍🏼👍🏽👍🏾👍🏿" />
                </Button>
        </InlineUIContainer>
        inline controls 📈
</TextBlock>

TextBox 文本框

文本框提供了一个用于键盘输入的区域。它可以用于单行或多行输入。

常用属性

你可能最常使用这些属性:

属性 描述
Text 输入中的当前文本。
PasswordChar 隐藏任何输入的字符,并用给定的字符代替。
Watermark 当输入为空时,显示为淡化的提示。
AcceptsReturn 允许用户输入换行符,使输入变为多行。如果内容超过可用高度,将出现垂直滚动条。
TextWrapping 定义如何处理水平行溢出。选项有:'NoWrap'、'Wrap' 和 'WrapWithOverflow'。

示例

此示例包含一个基本的单行文本框、一个密码框和一个文本换行的多行文本框:

<StackPanel Margin="20">
  <TextBlock Margin="0 5" >Name:</TextBlock>
  <TextBox  Watermark="Enter your name"/>
  <TextBlock Margin="0 5" >Password:</TextBlock>
  <TextBox PasswordChar="*" Watermark="Enter your password"/>
  <TextBlock Margin="0 15 0 5">Notes:</TextBlock>
  <TextBox Height="100" AcceptsReturn="True" TextWrapping="Wrap"/>
</StackPanel>

TimePicker 时间选择器

时间选择器有两个或三个"微调"控件,允许用户选择一个时间值。时间选择器可以使用24小时或12小时格式。当点击控件时,选择器控件会显示。

常用属性

你可能最常使用这些属性:

属性 描述
ClockIdentifier 选择12小时和24小时格式。12小时格式会显示一个用于AM/PM的第三个微调控件。
MinuteIncrement 定义分钟的可选增量。默认值为1(可以指定任意分钟数)。
SelectedTime (可空的TimeSpan)所选时间。

示例

此示例显示如何创建一个24小时制的时间选择器,时间间隔为20分钟:

<StackPanel Margin="20" Spacing="4">
    <Label Content="Please choose your time:"/>
    <TimePicker ClockIdentifier="24HourClock"
                MinuteIncrement="20"/>
</StackPanel>

初始化时间

你可以在XAML中将时间值设置为属性。使用 Hh:Mm 格式的字符串,其中 Hh 是小时,可以在0到23之间, Mm 是分钟,可以在0到59之间。

<TimePicker SelectedTime="09:15"/>

如果需要编写后台代码,可以这样写:

TimePicker timePicker = new TimePicker
{
    SelectedTime = new TimeSpan(9, 15, 0) // 秒数会被忽略。
};

你可以通过将所选时间重置为null来清除显示。

ToolTip 工具提示

工具提示是一个弹出窗口,当用户将鼠标悬停在附加到的"宿主"控件上时显示其内容。

常用属性

你可能最常使用这些属性:

属性 描述
ToolTip.Tip 工具提示内容的附加属性。
ToolTip.Placement 定义工具提示相对于宿主或指针的位置。可选择顶部、底部、左侧、右侧、锚点和重力、指针。默认值是指针,它将提示内容放置在指针停止移动的位置。
ToolTip.HorizontalOffset 工具提示相对于位置的水平偏移(默认值为0)。
ToolTip.VerticalOffset 工具提示相对于位置的垂直偏移(默认值为20)。
ToolTip.ShowDelay 指针必须保持静止的时间,工具提示才会出现。以微秒为单位(默认值为400)。

示例

这是一个简单的基于文本的工具提示,使用默认的放置和延迟属性值;此矩形放置在具有较大尺寸的窗口中:

<Rectangle Fill="Aqua" Height="200" Width="400"
      ToolTip.Tip="This is a rectangle" />

要为工具提示提供更丰富的呈现,请使用 <ToolTip.Tip> 元素。例如:

<Rectangle Fill="Aqua" Height="200" Width="400"
  ToolTip.Placement="Bottom">
  <ToolTip.Tip>
    <StackPanel>
    <TextBlock FontSize="16">Rectangle</TextBlock>
    <TextBlock>Some explanation here.</TextBlock>
    </StackPanel>
  </ToolTip.Tip>
</Rectangle>

TransitioningContentControl 切换内容控件

切换内容控件可以使用页面过渡来为内部控件的内容更改添加动画。

您可以使用此控件在幻灯片中显示不同图像的集合。

常用属性

你可能最常使用这些属性:

属性 描述
Content 要在控件中显示的内容。
TransitioningContentControl.ContentTemplate 用于显示内容的数据模板。
TransitioningContentControl.PageTransition 用于为内容更改添加动画的页面过渡。应用的主题将提供默认的页面过渡。要禁用过渡,请将此属性设置为 null。

示例

在此示例中,视图模型包含一个不同图像的集合,以在幻灯片中显示它们。以下 XAML 将使用默认的页面过渡来更改图像(在数据模板中),每当绑定的 SelectedImage 属性更改时:

<TransitioningContentControl Content="{Binding SelectedImage}" >
    <TransitioningContentControl.ContentTemplate>
        <DataTemplate DataType="Bitmap">
            <Image Source="{Binding}" />
        </DataTemplate>
    </TransitioningContentControl.ContentTemplate>
</TransitioningContentControl>

在此示例中,指定了不同的页面过渡以水平滑动图像:

<TransitioningContentControl Content="{Binding SelectedImage}" >
    <TransitioningContentControl.PageTransition>
        <PageSlide Orientation="Horizontal" Duration="0:00:00.500" />
    </TransitioningContentControl.PageTransition>
    <TransitioningContentControl.ContentTemplate>
        <DataTemplate DataType="Bitmap">
            <Image Source="{Binding}"  />
        </DataTemplate>
    </TransitioningContentControl.ContentTemplate>
</TransitioningContentControl>

TrayIcon 托盘图标

概述

托盘图标允许 Avalonia UI 应用程序在系统托盘中显示图标和本地菜单。它支持 WindowsmacOS 和一些 Linux 发行版(已确认在 Ubuntu 上工作)。

您必须在应用程序的 XAML 文件中定义托盘菜单。

常用属性

你可能最常使用这些属性:

属性 描述
Icon 在系统托盘中显示的图标。通常从应用程序资源中加载。
ToolTipText 当用户将鼠标悬停在托盘图标上时显示的工具提示文本。
TrayIcon.Menu 附加到托盘图标的本地菜单控件。

信息

您必须使用托盘图标的本地菜单 ,而不是 Avalonia UI 菜单控件。有关本地菜单的详细信息,请参见此处的参考。

示例

此示例在 App.xaml 文件中定义了一个简单的托盘图标菜单:

<TrayIcon.Icons>
  <TrayIcons>
    <TrayIcon Icon="/Assets/avalonia-logo.ico" 
              ToolTipText="Avalonia Tray Icon ToolTip">
      <TrayIcon.Menu>
        <NativeMenu>
          <NativeMenuItem Header="Settings">
            <NativeMenu>
              <NativeMenuItem Header="Option 1"   />
              <NativeMenuItem Header="Option 2"   />
              <NativeMenuItemSeparator />
              <NativeMenuItem Header="Option 3"  />
            </NativeMenu>
          </NativeMenuItem>
        </NativeMenu>
      </TrayIcon.Menu>
    </TrayIcon>
  </TrayIcons>
</TrayIcon.Icons>

TreeDataGrid 树状数据表格

TreeDataGrid 在单个视图中同时显示分层数据和表格数据。它是树视图和数据网格的组合。

信息

有关树视图控件的完整信息,请参见此处的参考。

信息

有关数据网格控件的完整信息,请参见此处的参考。

该控件有两种操作模式:

  • 分层 - 数据以树形结构显示,并带有可选列
  • 平面 - 数据以二维表格显示,类似于数据网格控件

分层数据

这是一个显示分层数据的树数据网格的示例:

平面数据

这是一个显示平面数据的树数据网格的示例:

NuGet 包引用

您必须安装数据网格的 NuGet 包,有几种方法可以做到这一点。您可以使用 IDE 项目菜单中的 Manage NuGet Packages

或者,您可以从命令行运行以下指令:

dotnet add package Avalonia.Controls.TreeDataGrid

或者直接将包引用添加到项目 (.csproj) 文件中:

<PackageReference Include="Avalonia.Controls.TreeDataGrid" Version="11.0.0" />

注意

注意,您必须始终安装与您使用的 Avalonia UI 版本匹配的数据网格版本。

包含数据网格样式

您必须引用数据网格主题以包含树数据网格使用的附加样式。您可以通过在应用程序 (App.axaml 文件) 中添加 <StyleInclude> 元素来实现这一点。

例如:

<Application xmlns="https://github.com/avaloniaui"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       x:Class="AvaloniaApplication.App">
  <Application.Styles>
  <FluentTheme/>
  <StyleInclude 
    Source="avares://Avalonia.Controls.TreeDataGrid/Themes/Fluent.axaml"/>
  </Application.Styles>
</Application>

有用的属性

您可能最常使用这些属性:

属性 描述
Source 用作控件数据源的绑定集合。
CanUserResizeColumns 指示用户是否可以使用指针调整列宽。(默认值为 false。)
CanUserSortColumns 指示用户是否可以通过单击列标题对列进行排序。(默认值为 true。)

Source

您将使用 Source 属性绑定到代码中定义的视图模型。视图模型包括列如何映射到保存网格项的类的属性的定义。

扁平树数据表格

示例

在此示例中,视图模型包含一个可观察集合,该集合填充了数据,然后用于创建一个 FlatTreeDataGridSource 属性以绑定到树数据网格的源。网格的项是 Person 类。

<TreeDataGrid Source="{Binding PersonSource}"/>

C# View Model

using Avalonia.Controls.Models.TreeDataGrid;
using Avalonia.Controls;
using AvaloniaControls.Models;
using System.Collections.ObjectModel;
using System.Linq;

namespace AvaloniaControls.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        private ObservableCollection<Person> _people;

        public FlatTreeDataGridSource<Person> PersonSource { get; }

        public MainWindowViewModel()
        {
            _people = new ObservableCollection<Person>()
            {
                new Person ("Eleanor", "Pope", 32 ),
                new Person ("Jeremy", "Navarro", 74 ),
                new Person ( "Lailah ", "Velazquez", 16 ),
                new Person ( "Jazmine", "Schroeder", 52 ),
            };
                          
            PersonSource = new FlatTreeDataGridSource<Person>(_people)
            {
                Columns =
                {
                    new TextColumn<Person, string>
                        ("First Name", x => x.FirstName),
                    new TextColumn<Person, string>
                        ("Last Name", x => x.LastName),
                    new TextColumn<Person, int>
                        ("Age", x => x.Age),
                },
            };
        }
    }
}

C# Item Class

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public Person(string firstName, string lastName, int age)
    {
        FirstName = firstName;
        LastName = lastName;
        Age = age;
    }
}

数据源还定义了如何将数据模型映射到树数据网格中的行和列。因为此示例显示的是扁平数据,所以数据源在视图模型上使用 FlatTreeDataGridSource<Person> 属性。

使用 TextColumn 类定义了三列。每个列都使用一个 lambda 表达式来返回列值。

分层树数据表格

示例

在此示例中,视图模型包含一个可观察集合,该集合填充了数据,然后用于创建一个 HierarchicalTreeDataGridSource 属性,以绑定到树数据网格的源。网格的项目是类 Person

<TreeDataGrid Source="{Binding PersonSource}"/>

C# View Model

using Avalonia.Controls.Models.TreeDataGrid;
using Avalonia.Controls;
using AvaloniaControls.Models;
using System.Collections.ObjectModel;
using System.Linq;

namespace AvaloniaControls.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        private ObservableCollection<Person> _people;

        public HierarchicalTreeDataGridSource<Person> PersonSource { get; }

        public MainWindowViewModel()
        {
            _people = new ObservableCollection<Person>()
            {
                new Person
                {
                    FirstName = "Eleanor", 
                    LastName = "Pope",
                    Age = 32,
                    Children =
                    {
                        new Person
                        { 
                            FirstName = "Marcel", 
                            LastName = "Gutierrez", 
                            Age = 4 
                        },
                    }
                },
                new Person
                {
                    FirstName = "Jeremy",
                    LastName = "Navarro",
                    Age = 74,
                    Children =
                    {
                        new Person
                        {
                            FirstName = "Jane",
                            LastName = "Navarro",
                            Age = 42 ,
                            Children =
                            {
                                new Person 
                                { 
                                    FirstName = "Lailah ", 
                                    LastName = "Velazquez", 
                                    Age = 16 
                                }
                            }
                        },
                    }
                },
                new Person 
                { 
                    FirstName = "Jazmine", 
                    LastName = "Schroeder", 
                    Age = 52 
                },
            };

            PersonSource = new HierarchicalTreeDataGridSource<Person>(_people)
            {
                Columns =
                {
                    new HierarchicalExpanderColumn<Person>(
                        new TextColumn<Person, string>
                            ("First Name", x => x.FirstName),x => x.Children),
                    new TextColumn<Person, string>
                            ("Last Name", x => x.LastName),
                    new TextColumn<Person, int>("Age", x => x.Age),
                },
            };
        }
    }
}

C# Item Class

public class Person
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public int Age { get; set; }
    public ObservableCollection<Person> Children { get; } = new();
}

数据源还定义了如何将数据模型映射到树数据网格中的行和列。因为此示例显示的是分层数据,所以数据源在视图模型上使用 HierarchicalTreeDataGridSource<Person> 属性。

定义了三列:

第一列用 HierarchicalExpanderColumn 包围。此元素包含一个 TextColumn,它采用一个 lambda 来返回列值,另一个返回行的子项。该列将显示一个带有折叠或展开子行(如果有)的按钮。其余列仅用 TextColumn 定义。

树形数据表格列类型

树形数据网格支持三种不同的列类型:

  • 文本列
  • 层次结构展开列
  • 模板列

文本列

文本列(类 TextColumn)在您希望列中的单元格具有文本值时非常有用。可以这样创建文本列:

new TextColumn<ItemClass, string>("Column Header", x => x.Property)

这里的第一个泛型参数是构成网格行的项目的类。第二个泛型参数是属性的类型。

上图是 TextColumn 构造函数的签名。前两个参数是必需的:第一个是列标题,第二个是获取属性值的表达式。

TextColumn 类实现了列接口 IColumn

层次结构展开列

层次结构展开列(类:HierarchicalExpanderColumn)只能与 层次结构 数据操作模式一起使用,并且必须与数据源类 HierarchicalTreeDataGridSource 一起使用。此列类型必须包含一个内部列(接口 IColumn)来定义其标题和值属性。层次结构展开列在层次树数据网格中显示展开和收缩的按钮。

这种列类型可以这样创建:

new HierarchicalExpanderColumn<ItemClass>(
    new TextColumn<ItemClass, string>("Column Header", x => x.Property), 
    x => x.Children)

泛型参数是构成网格行的项目的类。这与内部列的项目类相同。

上图是 HierarchicalExpanderColumn 构造函数的签名。构造函数中的第一个参数是内部列,第二个参数是(可为空的)子元素选择器。

模板列

模板列(类 TemplateColumn)是一种完全可定制的方式来创建列。它本质上为列形成一个数据模板

您可以这样创建模板列:

new TemplateColumn<ItemClass>("Column Header",
       new FuncDataTemplate<T>((a,e) => new SomeControl()))

上图是 TemplateColumn 构造函数的签名。它有两个必需的参数:第一个是列标题,第二个是返回 IDataTemplate 的函数。

TreeView 树视图

树视图控件可以呈现层次数据并允许项目选择。项目是模板化的,因此您可以自定义它们的显示方式。

有两个数据源:控件的主要项目源,这提供了层次数据的根。然后是项目模板中的项目源,它允许控件列出层次数据的下一级。

示例

此示例使用 MVVM 模式视图模型来保存一些基于 C# 节点类的层次数据。在此示例中,视图模型的 Nodes 集合中有一个根节点:

<TreeView ItemsSource="{Binding Nodes}">
    <TreeView.ItemTemplate>
        <TreeDataTemplate ItemsSource="{Binding SubNodes}">
            <TextBlock Text="{Binding Title}"/>
        </TreeDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

C# View Model

using AvaloniaControls.Models;
using System.Collections.ObjectModel;

namespace AvaloniaControls.ViewModels
{
        public class MainWindowViewModel : ViewModelBase
        {
                public ObservableCollection<Node> Nodes{ get; }

                public MainWindowViewModel()
                {
                        Nodes = new ObservableCollection<Node>
                        {                
                                new Node("Animals", new ObservableCollection<Node>
                                {
                                        new Node("Mammals", new ObservableCollection<Node>
                                        {
                                                new Node("Lion"), new Node("Cat"), new Node("Zebra")
                                        })
                                })
                        };
                }
        }
}

C# Node Class

using System.Collections.ObjectModel;

namespace AvaloniaControls.Models
{
        public class Node
        {
                public ObservableCollection<Node>? SubNodes { get; }
                public string Title { get; }
    
                public Node(string title)
                {
                        Title = title;
                }

                public Node(string title, ObservableCollection<Node> subNodes)
                {
                        Title = title;
                        SubNodes = subNodes;
                }
        }
}

默认情况下显示根节点(或节点)。用户可以通过单击相邻的箭头来展开或收缩每个节点。单击节点标题选择项目。

这是前一个示例的开发版本,具有多个根节点、修订的项目模板以及在视图模型代码中进行的初始选择:

<TreeView Margin="10"
                    ItemsSource="{Binding Nodes}" 
                    SelectedItems="{Binding SelectedNodes}"
                    SelectionMode="Multiple">
    <TreeView.ItemTemplate>
        <TreeDataTemplate ItemsSource="{Binding SubNodes}">
            <Border HorizontalAlignment="Left"
                            BorderBrush="Gray" BorderThickness="1"
                            CornerRadius="5" Padding="15 3">
                <TextBlock Text="{Binding Title}" />
            </Border>
        </TreeDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

C# View Model

using AvaloniaControls.Models;
using System.Collections.ObjectModel;
using System.Linq;

namespace AvaloniaControls.ViewModels
{
        public class MainWindowViewModel : ViewModelBase
        {
                public ObservableCollection<Node> Nodes { get; }
                public ObservableCollection<Node> SelectedNodes { get; }

                public MainWindowViewModel()
                {
                        SelectedNodes = new ObservableCollection<Node>();
                        Nodes = new ObservableCollection<Node>
                        {                
                                new Node("Animals", new ObservableCollection<Node>
                                {
                                        new Node("Mammals", new ObservableCollection<Node>
                                        {
                                                new Node("Lion"), new Node("Cat"), new Node("Zebra")
                                        })
                                }),
                                new Node("Birds", new ObservableCollection<Node>
                                {
                                        new Node("Robin"), new Node("Condor"), 
                                        new Node("Parrot"), new Node("Eagle")
                                }),
                                new Node("Insects", new ObservableCollection<Node>
                                {
                                        new Node("Locust"), new Node("House Fly"), 
                                        new Node("Butterfly"), new Node("Moth")
                                }),
                        };

                        var moth = Nodes.Last().SubNodes?.Last();
                        if (moth!=null) SelectedNodes.Add(moth);    
                }
        }
}

C# Node Class

using System.Collections.ObjectModel;

namespace AvaloniaControls.Models
{
        public class Node
        {
                public ObservableCollection<Node>? SubNodes { get; }
                public string Title { get; }
    
                public Node(string title)
                {
                        Title = title;
                }

                public Node(string title, ObservableCollection<Node> subNodes)
                {
                        Title = title;
                        SubNodes = subNodes;
                }
        }
}

树视图在需要时添加滚动条。可以通过按住 Ctrl 键来扩展选择。

UniformGrid 均匀网格

Uniform Grid 将可用空间在两个方向上均匀地划分为单元格。您可以指定使用多少个划分,并且这些划分在两个方向上可以不同。

然后,您可以使用附加的行和列索引属性(从零开始)将子控件分配到创建的单元格中。

常用属性

您可能最常使用这些属性:

属性 描述
Rows 整数。设置高度中相等行的数量。
Columns 整数。设置宽度中相等列的数量。
Grid.Column 附加到子控件以设置其列索引。
Grid.Row 附加到子控件以设置其行索引。

示例

<UniformGrid Rows="1" Columns="3" Width="300" Height="200">
    <Rectangle Fill="navy" Grid.Column="0" Grid.Row="0"/>
    <Rectangle Fill="white" Grid.Column="1" Grid.Row="0"/>
    <Rectangle Fill="red" Grid.Column="2" Grid.Row="0"/>
</UniformGrid>

Viewbox 视图盒

Viewbox 是一个可以缩放其内容的容器控件。可以定义内容的拉伸方式,以及拉伸发生的方向(拉伸方向)。

常用属性

你可能最常使用这些属性:

属性 默认值 描述
Stretch Uniform 决定内容如何适应可用空间。
StretchDirection Both 决定缩放何时发生。

Stretch 属性的值如下:

Stretch 描述
Uniform (默认) 内容被调整大小以适应容器的尺寸,同时保持其原生的宽高比。
Fill 内容被调整大小以填充容器的尺寸。宽高比不被保持。
UniformToFill 内容被调整大小以完全填充容器,同时保持其原生的宽高比。然而,如果内容的宽高比与分配空间的宽高比不匹配,则内容的一部分可能会被隐藏。

StretchDirection 属性的值如下:

Stretch Direction 描述
UpOnly 仅当内容小于可用空间时才缩放内容。如果内容较大,则不进行缩小。
DownOnly 仅当内容大于可用空间时才缩放内容。如果内容较小,则不进行放大。
Both (默认) 始终根据拉伸模式适应可用空间。

示例

这个简单的示例展示了一个 Viewbox 以统一的方式放大一个圆(拉伸和方向均为默认值)。

<Viewbox Stretch="Uniform" Width="300" Height="300">
   <Ellipse Width="50" Height="50" Fill="CornflowerBlue" />  
</Viewbox>

演示

以下演示展示了不同的拉伸和拉伸方向属性设置的组合效果。第一组展示了拉伸属性的效果:

Stretch 值 演示
Uniform
UniformToFill
Fill
None

第二组演示展示了拉伸方向属性的效果:

Stretch Direction 演示
UpOnly
DownOnly

Window 窗口

Window 是一个顶级的 ContentControl

通常情况下,你不会直接创建 Window 类的实例;相反,通常会为应用程序要显示的每种类型的窗口子类化 Window 类。有关如何从模板创建新窗口类的信息,请参见 快速入门

常见属性

属性 描述
Title 窗口标题
Icon 窗口图标
SizeToContent 描述窗口的自动调整大小行为
WindowState 窗口的最小化/最大化状态

源代码

Window.cs

显示、隐藏和关闭窗口

你可以使用 Show 方法显示一个窗口:

var window = new MyWindow();
window.Show();

可以使用 Close 方法关闭窗口。这与用户点击窗口的关闭按钮时的效果相同:

window.Close();

// 已关闭的窗口不能再次显示。
window.Show();

请注意,一旦窗口被关闭,就不能再次显示。如果你想重新显示窗口,应该使用 Hide 方法:

window.Hide();

// 现在窗口可以在以后再次显示
window.Show();

另见 阻止窗口关闭

以对话框形式显示窗口

你可以通过调用 ShowDialog 方法以模态对话框形式显示一个窗口。ShowDialog 需要传递一个所有者窗口:

// 这里我们假设这段代码是在我们当前的 Window 类中执行的,"this" 对象是一个 Window。
// 或者你可以从 Application.ApplicationLifetime 获取全局的 MainWindow 并转换为 IClassicDesktopStyleApplicationLifetime。
var ownerWindow = this;
var window = new MyWindow();
window.ShowDialog(ownerWindow);

ShowDialog 方法将立即返回。如果你想等待对话框关闭,可以 await 调用:

var window = new MyWindow();
await window.ShowDialog(ownerWindow);

对话框可以通过调用带有对象的 Close 方法返回一个结果。然后,调用 ShowDialog 的方可以读取这个结果。例如:

public class MyDialog : Window
{
    public MyDialog()
    {
        InitializeComponent();
    }

    private void OkButton_Click(object sender, EventArgs e)
    {
        Close("OK Clicked!");
    }
}

var dialog = new MyDialog();

// 结果是一个字符串,所以调用 `ShowDialog<string>`。
var result = await dialog.ShowDialog<string>(ownerWindow);

阻止窗口关闭

可以通过处理 Closing 事件并设置 e.Cancel = true 来阻止窗口关闭:

window.Closing += (s, e) =>
{
    e.Cancel = true;
};

你也可以选择隐藏窗口。这允许在用户点击关闭按钮后重新显示窗口:

window.Closing += (s, e) =>
{
    ((Window)s).Hide();
    e.Cancel = true;
};

WrapPanel 顺序换行面板

WrapPanel 使用默认排列方式将多个子元素从左到右依次排列,直到宽度不够时换行(包括任何边距和边框)。当没有剩余空间时,它会开始新的一行。

当 Orientation 属性设置为 Vertical 时,排列方式为从上到下,当没有剩余高度时开始新的一列。

常用属性

你可能最常使用这些属性:

属性 描述
Orientation 更改排列方向。

示例

<WrapPanel>
    <Rectangle Fill="Navy" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Yellow" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Green" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Red" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Purple" Width="100" Height="100" Margin="20"/>
</WrapPanel>
<WrapPanel Orientation="Vertical">
    <Rectangle Fill="Navy" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Yellow" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Green" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Red" Width="100" Height="100" Margin="20"/>
    <Rectangle Fill="Purple" Width="100" Height="100" Margin="20"/>
</WrapPanel>

PinchGestureRecognizer 捏合手势识别器

一个用于追踪捏合手势的手势识别器。捏合手势发生在两个触控点向彼此靠近或远离的情况下。这在实现捏合缩放交互的控件中非常有用。

使用捏合手势识别器

可以通过将 PinchGestureRecognizer 添加到控件的 GestureRecognizers 属性来将其附加到控件上。

<Image Stretch="UniformToFill"
        Margin="5"
        Name="image"
        Source="/image.jpg">
  <Image.GestureRecognizers>
    <PinchGestureRecognizer/>
  </Image.GestureRecognizers>
</Image>

C#

image.GestureRecognizers.Add(new PinchGestureRecognizer());

PinchGestureRegonizer 检测到拉动手势的开始时,会触发 Gestures.PinchEvent 事件。当拉动结束(指针被释放或开始另一个手势)时,它会触发 Gestures.PinchEndedEvent 事件。 传递给 Gestures.PinchEvent 事件处理程序的参数中的 Scale 属性包含自从捏合手势开始以来的相对大小。

PullGestureRecognizer 拉动手势识别器

一个用于追踪拉动手势的手势识别器。拉动手势发生在指针从控件的边缘拖动时。拉动的方向由 PullDirection 属性定义。

使用拉动手势识别器

可以通过将 PullGestureRecognizer 添加到控件的GestureRecognizers属性来将其附加到控件上。

<Border Width="500"
        Height="500"
        Margin="5"
        Name="border">
  <Border.GestureRecognizers>
    <PullGestureRecognizer PullDirection="TopToBottom"/>
  </Border.GestureRecognizers>
</Border>

C#

border.GestureRecognizers.Add(new PullGestureRecognizer()
            {
                PullDirection = PullDirection.TopToBottom,
            });

PullGestureRegonizer 检测到拉动手势的开始时,会引发Gestures.PullGestureEvent事件。当拉动结束,即指针被释放或另一个手势开始时,它会引发Gestures.PullGestureEndedEvent事件。

PullDirection

这定义了拉动的方向。有4个可用的值:

  • PullDirection.TopToBottom : 拉动从顶部边缘开始向下移动

  • PullDirection.BottomToTop : 拉动从底部边缘开始向上移动

  • PullDirection.LeftToRight : 拉动从左边缘开始向右移动

  • PullDirection.RightToLeft : 拉动从右边缘开始向左移动

有用的属性

您可能经常使用以下属性:

属性 描述
PullDirection 定义拉动手势的方向。

ScrollGestureRecognizer 滚动手势识别器

一个用于跟踪滚动手势的手势识别器。可以将其附加到控件上,以便在控件的边界内检测指针在特定方向上的移动。当控件水平、垂直或同时进行内容平移时,这将特别有用。

使用滚动手势识别器

可以使用控件的 GestureRecognizers 属性将 ScrollGestureRecognizer 附加到控件上。

<Image Stretch="UniformToFill"
        Margin="5"
        Name="image"
        Source="/image.jpg">
  <Image.GestureRecognizers>
    <ScrollGestureRecognizer CanHorizontallyScroll="True"
                              CanVerticallyScroll="True"/>
  </Image.GestureRecognizers>
</Image>

C#

image.GestureRecognizers.Add(new ScrollGestureRecognizer()
            {
                CanVerticallyScroll = true,
                CanHorizontallyScroll = true,
            });

ScrollGestureRecognizer 检测到滚动手势的开始时,它会引发 Gestures.ScrollGestureEvent 事件。当滚动结束(指针释放或其他手势开始)时,它会引发 Gestures.ScrollGestureEndedEvent 事件。

有用的属性

You will probably use these properties most often:

属性 描述
CanVerticallyScroll 定义内容是否可以垂直滚动。
CanHorizontallyScroll 定义内容是否可以水平滚动。
相关推荐
禁默12 分钟前
2024年图像处理、多媒体技术与机器学习
图像处理·人工智能·microsoft
晓纪同学3 小时前
QT创建一个模板槽和信号刷新UI
开发语言·qt·ui
坐井观老天3 小时前
在C#中使用资源保存图像和文本和其他数据并在运行时加载
开发语言·c#
Zmxcl-0074 小时前
IIS解析漏洞
服务器·数据库·microsoft
pchmi5 小时前
C# OpenCV机器视觉:模板匹配
opencv·c#·机器视觉
蚁景网络安全7 小时前
Cobalt Strike 4.8 用户指南-第十四节 Aggressor 脚本
windows·microsoft
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭7 小时前
C#都可以找哪些工作?
开发语言·c#
boligongzhu9 小时前
Dalsa线阵CCD相机使用开发手册
c#
向宇it21 小时前
【从零开始入门unity游戏开发之——C#篇23】C#面向对象继承——`as`类型转化和`is`类型检查、向上转型和向下转型、里氏替换原则(LSP)
java·开发语言·unity·c#·游戏引擎·里氏替换原则