DataGrid 数据表格
数据表格以自定义的网格形式展示重复的数据。该控件可以进行样式定制、模板化和绑定。
数据表格需要绑定到一个可观察的集合(Observable Collection),该集合可以在相关的数据上下文中找到。
信息
要了解数据上下文 背后的概念,请查看这里。
信息
数据表格位于附加的 Avalonia UI 包中。要在您的项目中使用数据表格,您必须引用Avalonia.Controls.DataGrid NuGet 包,并引用其使用的样式,参见下面。
NuGet包引用
您必须安装数据表格的 NuGet 包,有几种方法可以做到这一点。您可以使用您的IDE的项目菜单中的管理NuGet包:
或者,您可以在命令行中运行以下指令:
dotnet add package Avalonia.Controls.DataGrid
或直接在项目(.csproj
)文件中添加包引用:
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.0" />
注意
请注意,您必须始终安装与您正在使用的 Avalonia UI 版本匹配的数据表格版本。
引入数据表格样式
您必须引用数据表格的主题,以包含数据表格使用的附加样式。您可以通过向应用程序(App.axaml
文件)添加<StyleInclude>
元素来实现这一点。
例如:
<Application.Styles>
<FluentTheme />
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
</Application.Styles>
常用属性
您可能经常使用以下属性:
属性 | 描述 |
---|---|
AutoGenerateColumns |
是否根据绑定项数据源属性名称自动生成列头。 (默认关闭) |
ItemsSource |
作为控件数据源的绑定集合。 |
IsReadOnly |
当为true时,将绑定方向设置为单向。默认值为false,网格将接受对绑定数据的更改。 |
CanUserReorderColumns |
用户是否可以通过拖动列头更改列的显示顺序。 (默认关闭) |
CanUserResizeColumns |
用户是否可以使用指针调整列宽度。 (默认关闭) |
CanUserSortColumns |
用户是否可以通过单击列头对列进行排序。 (默认关闭) |
更多信息
这个示例将生成一个基本的数据表格,列头名称将根据项类自动生成。项目数据源绑定到主窗口的 ViewModel。
<DataGrid Margin="20" ItemsSource="{Binding People}"
AutoGenerateColumns="True" IsReadOnly="True"
GridLinesVisibility="All"
BorderThickness="1" BorderBrush="Gray">
</DataGrid>
ViewModel
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<Person> People { get; }
public MainWindowViewModel()
{
var people = new List<Person>
{
new Person("Neil", "Armstrong"),
new Person("Buzz", "Lightyear"),
new Person("James", "Kirk")
};
People = new ObservableCollection<Person>(people);
}
}
}
数据源 Person 类
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName , string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
信息
这些示例使用了MVVM模式和数据绑定到一个ObservableCollection
。要了解更多有关数据绑定背后的概念,请参阅这里。
通常来说,从数据源中获取的属性名称通常不会成为合适的列名。下面这个示例为表格添加了自定义的列头名称。它还允许列重新排序和调整大小,并禁用了默认的列排序选项:
<DataGrid Margin="20" ItemsSource="{Binding People}"
IsReadOnly="True"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
CanUserSortColumns="False"
GridLinesVisibility="All"
BorderThickness="1" BorderBrush="Gray">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" />
</DataGrid.Columns>
</DataGrid>
这个示例展示了数据表格如何接受更改并更新底层集合,并使用不同的列类型来编辑数据:
<DataGrid Margin="20" ItemsSource="{Binding People}"
GridLinesVisibility="All"
BorderThickness="1" BorderBrush="Gray">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" />
<DataGridCheckBoxColumn Header="Fictitious?" Binding="{Binding IsFictitious}" />
</DataGrid.Columns>
</DataGrid>
ViewModel
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<Person> People { get; }
public MainWindowViewModel()
{
var people = new List<Person>
{
new Person("Neil", "Armstrong", false),
new Person("Buzz", "Lightyear", true),
new Person("James", "Kirk", true)
};
People = new ObservableCollection<Person>(people);
}
}
}
数据源 Person 类
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsFictitious { get; set; }
public Person(string firstName , string lastName, bool isFictitious)
{
FirstName = firstName;
LastName = lastName;
IsFictitious = isFictitious;
}
}
数据表格模板列
您可以使用此列类型自定义数据网格列的显示和编辑。
有两个数据模板,您可以将其定义为附加属性:
数据模板 | 描述 |
---|---|
CellTemplate |
列值的显示(未编辑)呈现。 |
CellEditingTemplate |
列值的编辑模板。 |
信息
如果您未设置编辑模板,该列将保持只读状态。
示例
此示例在编辑某人的年龄属性时添加一个数字上下控件:
<Window ...
xmlns:model="using:AvaloniaControls.Models" >
<DataGrid Margin="20" ItemsSource="{Binding People}"
GridLinesVisibility="All"
BorderThickness="1" BorderBrush="Gray">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Width="2*"
Binding="{Binding FirstName}" />
<DataGridTextColumn Header="Last Name" Width="2*"
Binding="{Binding LastName}" />
<DataGridTemplateColumn Header="Age">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="model:Person">
<TextBlock Text="{Binding AgeInYears, StringFormat='{}{0} years'}"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate DataType="model:Person">
<NumericUpDown Value="{Binding AgeInYears}"
FormatString="N0" Minimum="0" Maximum="120"
HorizontalAlignment="Stretch"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Window>
C# View Model
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<Person> People { get; }
public MainWindowViewModel()
{
var people = new List<Person>
{
new Person("Neil", "Armstrong", 55),
new Person("Buzz", "Lightyear", 38),
new Person("James", "Kirk", 44)
};
People = new ObservableCollection<Person>(people);
}
}
}
C# Item Class
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int AgeInYears { get; set; }
public Person(string firstName , string lastName, int ageInYears)
{
FirstName = firstName;
LastName = lastName;
AgeInYears = ageInYears;
}
}
数据表格列
数据表格可以包含多个数据表格列,Avalonia UI 提供了两种内置列类型,用于显示不同的数据类型,还有一个可以自定义列外观的模板类型。
列类型 | 描述 |
---|---|
DataGridTextColumn |
用于显示和编辑列数据的文本框。您可以在此列类型中控制字体属性,比如字体家族和大小。 |
DataGridCheckBoxColumn |
用于显示和编辑列数据的复选框,当数据类型为布尔值时。此列类型还支持当值为可空时的三态复选框。 |
DataGridTemplateColumn |
可用于自定义列数据的展示和编辑。 |
常用属性
大部分属性在这三种列类型中都是通用的:
属性 | 描述 |
---|---|
Header |
列的标题内容。 |
HeaderTemplate |
使用数据模板作为列的标题。 |
IsReadOnly |
列是否为只读。如果数据表格本身是只读的,那么无论此属性的值如何,列都是只读的。 |
IsThreeState |
仅适用于复选框列。当可空布尔值为null时,启用第三个(填充)状态。 |
Width |
列宽度可以是绝对大小或相对大小(见下文)。 |
列宽度
如果您没有为列设置宽度,它将被调整以适应内容,并在必要时为网格添加水平滚动条。
您可以绝对设置列的宽度,例如:
<DataGridTextColumn Width="200" />
这将导致不适合的列内容被隐藏。
或者,您可以指定相对自动大小。这使用 * 表示可用宽度的等分,然后使用类似 2* 的倍数。未指定宽度的列将根据其内容调整大小。
例如,要将数据表格划分为3个等宽的列:
<DataGridTextColumn Width="*" />
<DataGridTextColumn Width="*" />
<DataGridTextColumn Width="*" />
示例
下面的示例通过将两列等宽展开来改进数据表格的外观:
<Window ... >
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<DataGrid Margin="20" ItemsSource="{Binding People}"
IsReadOnly="True"
GridLinesVisibility="All"
BorderThickness="1" BorderBrush="Gray">
<DataGrid.Columns>
<DataGridTextColumn Header="名字" Width="*"
Binding="{Binding FirstName}"/>
<DataGridTextColumn Header="姓氏" Width="*"
Binding="{Binding LastName}" />
</DataGrid.Columns>
</DataGrid>
</Window>
C# ViewModel
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<Person> People { get; }
public MainWindowViewModel()
{
var people = new List<Person>
{
new Person("Neil", "Armstrong"),
new Person("Buzz", "Lightyear"),
new Person("James", "Kirk")
};
People = new ObservableCollection<Person>(people);
}
}
}
数据源 Person 类
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName , string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
在预览窗口中可以看到效果,因为 <Design.DataContext>
元素创建了绑定的 ViewModel:
DatePicker 日期选择器
日期选择器包含三个"轮盘"控制器,允许用户选择日期值。点击控件时会显示这些旋转器。
常用属性
你可能最常使用这些属性:
属性 | 描述 |
---|---|
DayVisible |
设置是否显示日列。 |
MonthVisible |
设置是否显示月列。 |
YearVisible |
设置是否显示年列。 |
DayFormat |
日期中日部分的格式字符串。 |
MonthFormat |
日期中月部分的格式字符串。 |
YearFormat |
日期中年部分的格式字符串。 |
SelectedDate |
选择的日期(无选择时为 null)。 |
示例
此示例使用日期格式属性来显示星期名及日期号:
<StackPanel Margin="20">
<DatePicker DayFormat="ddd dd"/>
</StackPanel>
初始化日期
这个控件的日期属性不能在 XAML 中使用属性设置,因为没有可用的转换器来将字符串转换为日期对象,如 DateTime
和 DateTimeOffset
。
你需要编写如下 code-behind 代码:
datePicker.SelectedDate = new DateTimeOffset(new DateTime(1950, 1, 1));
Decorator 装饰器
Decorator
是用于装饰单个子控件的基础装饰器类。
参考资料
源代码
DockPanel 边缘布局面板
边缘布局面板(Dock Panel)控件可以沿着指定的"停靠边缘"(顶部、底部、左侧和右侧)排列其子控件,最后一个子控件填充剩余的空间。边缘布局面板可以保持与停靠边缘平行的子控件尺寸,使得子控件沿停靠边缘填满所有可用空间。
例如,如果一个子控件的停靠边缘被定义为"顶部",并且它有一个定义的高度但没有宽度,它将会这样绘制:
注意
你必须定义与停靠边缘垂直的子控件尺寸,否则它将不会显示。
你可以选择性地定义与停靠边缘平行的尺寸。在这种情况下,子控件将根据同一方向上的对齐设置进行绘制。例如,一个定义了宽度并停靠在顶部边缘的子控件,将遵循其水平对齐属性(默认居中)。
子控件按照它们在XAML中定义的顺序进行停靠。当 Avalonia UI 正在调整子控件的大小时,会考虑到任何先前绘制的控件。这意味着永远不会有重叠。
最后定义的子控件将填满任何剩余的空间。
注意
你必须始终定义一个最后的子控件(没有停靠属性),否则停靠计算将无法正确进行。这意味着一个边缘布局面板需要至少两个子控件。
常用属性
你可能最常使用这些属性:
属性 | 描述 |
---|---|
DockPanel.Dock.Left |
附加到一个子控件 - 将其停靠在左侧。 |
DockPanel.Dock.Top |
附加到一个子控件 - 将其停靠在顶部边缘。 |
DockPanel.Dock.Right |
附加到一个子控件 - 将其停靠在右侧。 |
DockPanel.Dock.Bottom |
附加到一个子控件 - 将其停靠在底部边缘。 |
示例
将橙色矩形的透明度设置为0.5,以证实图形间没有重叠。
<DockPanel Width="300" Height="300">
<Rectangle Fill="Red" Height="100" DockPanel.Dock="Top"/>
<Rectangle Fill="Blue" Width="100" DockPanel.Dock="Left" />
<Rectangle Fill="Green" Height="100" DockPanel.Dock="Bottom"/>
<Rectangle Fill="Orange" Width="100" DockPanel.Dock="Right" Opacity="0.5"/>
<Rectangle Fill="Gray" />
</DockPanel>
Expander 折叠面板
折叠面板控件具有一个标题区域(始终可见)和一个可折叠的内容部分,该内容部分可以包含单个子控件。
常用属性
你可能最常使用这些属性:
属性 | 描述 |
---|---|
Expander.Header | 定义标题区域中显示的内容。 |
示例
<Expander VerticalAlignment="Top">
<Expander.Header>
隐藏搜索
</Expander.Header>
<Grid RowDefinitions="*,*" ColumnDefinitions="150,*">
<TextBlock Grid.Row="0" Grid.Column="0"
VerticalAlignment="Center">搜索</TextBlock>
<TextBox Grid.Row="0" Grid.Column="1"
Watermark="搜索文本" Width="200" />
<TextBlock Grid.Row="1" Grid.Column="0"
VerticalAlignment="Center">区分大小写?</TextBlock>
<CheckBox Grid.Row="1" Grid.Column="1" />
</Grid>
</Expander>
Flyout 弹出层
弹出层是一种可关闭的容器,可以附加到某些类型的"宿主"控件上;尽管弹出层本身并不是控件。当宿主控件获得焦点时,弹出层会显示出来,并且可以通过多种不同的方式再次隐藏。
弹出层可以包含简单或更丰富的、组合的用户界面内容。
在 Avalonia UI 应用中,弹出层可以声明为资源,并在两个或更多宿主控件之间共享。
示例
通过宿主控件的 Flyout
属性附加弹出层。例如:
<Button Content="带弹出层的按钮">
<Button.Flyout>
<Flyout>这是按钮的弹出层</Flyout>
</Button.Flyout>
</Button>
注意
只有按钮和分隔按钮控件支持 Flyout
属性。你可以使用 AttachedFlyout
属性将弹出层附加到其他 Avalonia UI 内置控件上。
对于没有 Flyout
属性的控件,使用 AttachedFlyout
属性如下:
<Border Background="Red" PointerPressed="Border_PointerPressed">
<FlyoutBase.AttachedFlyout>
<Flyout>
<TextBlock Text="红色矩形弹出层" />
</Flyout>
</FlyoutBase.AttachedFlyout>
</Border>
弹出层不会自动显示,必须从 code-behind 显示。例如:
public void Border_PointerPressed(object sender, PointerPressedEventArgs args)
{
var ctl = sender as Control;
if (ctl != null)
{
FlyoutBase.ShowAttachedFlyout(ctl);
}
}
常用属性
你可能最常使用这些属性:
属性 | 描述 |
---|---|
Placement |
弹出层相对于其附加控件的打开位置。 |
ShowMode |
描述弹出层的显示和隐藏方式。请看下面的选项。 |
ShowMode
此设置描述弹出层的显示和隐藏方式:
模式 | 描述 |
---|---|
Standard |
当附加的控件获得焦点时显示弹出层。当附加的控件失去焦点时隐藏弹出层(用户切换焦点或点击其他地方)。 |
Transient |
在弹出层外做出操作时(如点击)消失。 |
TransientWithDismiss OnPointerMoveAway |
当光标移开一定距离后,弹出层自动消失。 |
所有弹出层的常用方法
属性 | 描述 |
---|---|
ShowAt(Control) |
在指定的目标控件上显示弹出层。 |
ShowAt(Control, bool) |
在指定的目标控件上显示弹出层,但位置基于当前指针位置。 |
Hide |
隐藏弹出层。 |
共享弹出层
你可以在应用中的两个或更多元素之间共享弹出层。例如,从窗口的资源集合中共享弹出层:
<Window.Resources>
<Flyout x:Key="MySharedFlyout">
<!-- 弹出层内容在此 -->
</Flyout>
</Window.Resources>
<Button Content="点击我!" Flyout="{StaticResource MySharedFlyout}" />
<Button Content="现在点击我!" Flyout="{StaticResource MySharedFlyout}" />
弹出层的样式定制
虽然弹出层本身不是控件,但可以通过Flyout
用来显示其内容的展示器来自定义其外观。对于普通的Flyout
,这个展示器是FlyoutPresenter
;对于MenuFlyout
,则是MenuFlyoutPresenter
。因为弹出层的展示器不是公开的,特定的弹出层相关的特殊样式类可以通过FlyoutBase
上的FlyoutPresenterClasses
属性传递:
<Style Selector="FlyoutPresenter.mySpecialClass">
<Setter Property="Background" Value="Red" />
</Style>
<Flyout FlyoutPresenterClasses="mySpecialClass">
<!-- 弹出层内容在此 -->
</Flyout>
Grid 网格布局
Grid
控件非常适用于按列和行排列子控件。您可以为 Grid
定义绝对大小、比例大小和自动大小的行和列几何形状。
每个位于 Grid
中的子控件都可以使用列和行坐标定位在 Grid
单元格中。这些坐标是从零开始的,并且默认值为零。
如果在同一单元格中定位多个子控件,它们将按照在 XAML 中出现的顺序在该单元格中绘制。这是实现层叠堆叠的另一种策略,除了使用 Panel
。
注意
如果您忽略了 Grid
的子控件的列和行坐标,它们都将被绘制在左上角(列=0,行=0)。
也可以使子控件跨越一个或多个单元格的行或列,或两者都跨越。
常用属性
您可能最常使用这些属性:
属性 | 描述 |
---|---|
ColumnDefinitions | Grid 中列宽的尺寸定义。 |
RowDefinitions | Grid 中行高的尺寸定义。 |
ShowGridLines | 显示单元格之间的网格线(作为虚线显示)。 |
Grid.Column | 将控件布局到指定的从零开始的列中。 |
Grid.Row | 将控件布局到指定的从零开始的行中。 |
Grid.ColumnSpan | 将控件跨越一个或多个列。 |
Grid.RowSpan | 将控件跨越一个或多个行。 |
Grid.IsSharedSizeScope | 定义控件为 SharedSizeGroup 的包含范围。 |
尺寸定义
您可以如下定义行和列的大小:
- 绝对大小 - 以设备独立像素(整数)为单位。
- 比例大小 - 根据剩余
Grid
大小的比例。 - 自动大小 - 根据包含的子控件的大小自动调整。
尺寸定义可以通过简短代码列表或使用 XAML 元素完全展开来编写。
完整定义支持额外的约束,如 SharedSizeGroup
和指定最小和最大长度的绝对大小。
绝对大小定义
绝对大小定义在列网格式中以整数形式编写。例如:
ColumnDefinitions="200, 200, 300"
通过完全展开的 XAML 定义,这与以下相同:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="300"></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
比例大小定义
比例大小定义使用星号表示可用 Grid
空间的比例。例如,要创建两个宽度相同的列,然后是一个宽度是前两个的两倍(单个宽度的两倍)的列:
ColumnDefinitions="*, *, 2*"
通过完全展开的 XAML 定义,这与以下相同:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
提示
尺寸定义不支持百分比。一个解决方法是创建一个定义,其中所有比例值加起来等于 100,例如 <Grid ColumnDefinitions="25*, 25*, 50*">
用于 3 个列,每个列分别占剩余可用宽度的 25%、25% 和 50%。
自动大小定义
要自动调整行或列的大小以适应其中最大的子控件,请使用 'Auto' 代码。例如:
RowDefinitions="Auto, Auto, Auto"
通过完全展开的 XAML 定义下相同:,这与以
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
</Grid>
注意
如果子控件有自己显式设置的尺寸,当绘制时将遵循这些尺寸。这意味着如果它大于其网格单元格,它将重叠相邻的单元格。
混合尺寸定义
您可以在同一尺寸定义序列中混合使用上述任何一种。例如:
ColumnDefinitions="200, *, 2*"
通过完全展开的 XAML 定义,这与以下相同:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
绘图规则
在计算尺寸时,任何比例列都将适应在计算绝对值和自动值后剩余的空间。
自动尺寸的计算是使用子控件的边距布局区域外缘进行的。
信息
要回顾控制布局区域的概念,请参阅此处。
子控件按照它们在 XAML 中出现的顺序在其分配的网格单元格中绘制。这条规则既适用于当两个子控件被分配到同一单元格时的情况,也适用于子控件大于其分配单元格时的重叠情况。
当子控件有自己的尺寸,并且小于其分配的单元格时,它将根据其水平和垂直对齐属性(默认都是居中)在单元格中对齐绘制。
示例
这个示例展示了:
- 如何使用简短语法定义列和行。
- 如何混合绝对和比例列宽。
- 如何为子控件分配单元格。
- 如何跨行和列。
一个包含 3 个相等行和 3 列(1 个固定宽度),(2 个按比例抓取剩余宽度)的 Grid
的示例是:
<Grid ColumnDefinitions="100,1.5*,4*" RowDefinitions="Auto,Auto,Auto" Margin="4">
<TextBlock Text="Col0Row0:" Grid.Row="0" Grid.Column="0"/>
<TextBlock Text="Col0Row1:" Grid.Row="1" Grid.Column="0"/>
<TextBlock Text="Col0Row2:" Grid.Row="2" Grid.Column="0"/>
<CheckBox Content="Col2Row0" Grid.Row="0" Grid.Column="2"/>
<Button Content="SpansCol1-2Row1-2" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2"/>
</Grid>
在这里,100 的绝对宽度被减去后(对于列 0),列 1 将获得 1.5 个部分,列 2 将获得剩余宽度的 4 个部分。
按钮被绘制以填充从单元格(列 1,行 1)加一个列(向右)和一行向下的跨度。结果看起来是这样的:
SharedSizeGroup
SharedSizeGroup
允许在多个 Grid
控件之间共享自动调整大小的行和列定义的大小信息。
示例
以下示例演示了如何使用 SharedSizeGroup
在 ListBox
内外一致地调整列的大小。
-
XML
-
C#
<StackPanel Grid.IsSharedSizeScope="True"> <StackPanel.Styles> <Style Selector="ListBoxItem"> <Setter Property="Padding" Value="0" /> </Style> </StackPanel.Styles>
</StackPanel><ListBox ItemsSource="{Binding People}"> <ListBox.ItemTemplate> <DataTemplate> <Grid Name="myGrid" RowDefinitions="auto, auto" ShowGridLines="True"> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="A" /> <ColumnDefinition SharedSizeGroup="B" /> <ColumnDefinition Width="*" /> <ColumnDefinition SharedSizeGroup="C" /> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Margin="6,0" Text="{Binding FirstName}" /> <TextBlock Grid.Column="1" Margin="6,0" Text="{Binding LastName}" /> <TextBlock Grid.Column="2" Margin="6,0" Text="{Binding Age}" /> <TextBlock Grid.Column="3" Margin="6,0" Text="{Binding Occupation}" /> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <!-- Controls may appear in-between Grids with SharedSizeGroups --> <Separator /> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="A" /> <ColumnDefinition SharedSizeGroup="B" /> <ColumnDefinition Width="*" /> <ColumnDefinition SharedSizeGroup="C" /> </Grid.ColumnDefinitions> <Button Content="This is the First Name" HorizontalAlignment="Stretch" Grid.Column="0" /> <Button Content="Last" HorizontalAlignment="Stretch" Grid.Column="1" /> <Button Content="Age" HorizontalAlignment="Stretch" Grid.Column="2" /> <Button Content="Occupation" HorizontalAlignment="Stretch" Grid.Column="3" /> </Grid>
请注意每列的大小:第一列由 Button
调整大小,第二列和第四列由 ListBox
内容调整大小,第三列占用剩余空间。
GridSplitter 网格分割器
网格分割器控件允许用户在运行时调整网格中的列或行的大小。分割器被绘制为一列或一行(可以指定大小),并具有一个用户可以在运行时操作的把手。
常用属性
你可能最常使用这些属性:
属性 | 描述 |
---|---|
Background |
分割条的背景颜色。 |
Grid.Column |
附加属性,用来指定分割器的列位置。 |
Grid.Row |
附加属性,用来指定分割器的行位置。 |
ResizeDirection |
分割器的移动方向。(见下面的注释) |
注意
为了提供任何有意义的移动,分割器的移动方向必须与其位置定义相同。即:对于列分割器指定 ResizeDirection="Columns"
,对于行分割器指定 ResizeDirection="Rows"
。
示例
这是一个列分割器:
<Grid ColumnDefinitions="*, 4, *">
<Rectangle Grid.Column="0" Fill="Blue"/>
<GridSplitter Grid.Column="1" Background="Black" ResizeDirection="Columns"/>
<Rectangle Grid.Column="2" Fill="Red"/>
</Grid>
这是一个行分割器:
<Grid RowDefinitions="*, 4, *">
<Rectangle Grid.Row="0" Fill="Blue"/>
<GridSplitter Grid.Row="1" Background="Black" ResizeDirection="Rows"/>
<Rectangle Grid.Row="2" Fill="Red"/>
</Grid>
Image 图像
图像可以从指定的图像源显示栅格图像。源可以是:
- 一个字符串常量,对应一个应用程序资源,
- 从资源的绑定名称加载为位图(通过使用绑定转换器),
- 或者可以直接从内存流加载为位图。
图像可以用来组成其他控件的内容。例如,您可以使用图像控件创建一个图形按钮。
显示的图像可以被调整大小和缩放。默认的缩放设置(两个方向上均匀拉伸)将导致图像适应给定的大小(宽度和/或高度)。
信息
图像的缩放设置与视图框的相同,参见ViewBox。
示例
此示例展示了一个位图资源被加载到图像控件中,其中高度和宽度被限制,但缩放设置保持默认。图像本身不是正方形,但图像的宽度和高度设置为相同的值。包括矩形是为了给出图像被缩放的一个概念:
<Panel>
<Rectangle Height="300" Width="300" Fill="LightGray"/>
<Image Margin="20" Height="200" Width="200"
Source="avares://AvaloniaControls/Assets/pipes.jpg"/>
</Panel>
在下一个示例中,引入了 UniformToFill
的拉伸设置,使得图像完全填满指定的高度,但会裁剪掉超出指定宽度的部分。图像没有因此处理而失真。
<Panel>
<Rectangle Height="300" Width="300" Fill="LightGray"></Rectangle>
<Image Margin="20" Height="200" Width="200"
Stretch="UniformToFill"
Source="avares://AvaloniaControls/Assets/pipes.jpg"/>
</Panel>
ItemsControl 元素集合控件
元素集合控件是用于显示重复数据的控件(例如列表框)的基础。它本身不包含内置的格式化或交互功能;但你可以结合数据绑定、样式和数据模板使用,创建一个完全自定义的重复数据控件。
信息
要查看 Avalonia UI 内置的所有重复数据控件的完整列表,请查看这里。
常用属性
你可能最常使用这些属性:
属性 | 描述 |
---|---|
ItemsSource |
用作控件数据源的绑定集合。 |
ItemsControl.ItemTemplate |
附加属性元素,包含单个元素的数据模板。 |
示例
此示例将一个可观察的餐具项集合绑定到一个元素控件,其中通过数据模板提供了一些自定义布局和格式化:
<StackPanel Margin="20">
<TextBlock Margin="0 5">餐具列表:</TextBlock>
<ItemsControl ItemsSource="{Binding CrockeryList}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="0,10,0,0"
CornerRadius="5"
BorderBrush="Gray" BorderThickness="1"
Padding="5">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}"/>
<TextBlock Margin="5 0" FontWeight="Bold"
Text="{Binding Number}"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
C# ViewModel
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<Crockery> CrockeryList { get; set; }
public MainWindowViewModel()
{
CrockeryList = new ObservableCollection<Crockery>(new List<Crockery>
{
new Crockery("晚餐盘", 12),
new Crockery("小碟", 12),
new Crockery("早餐碗", 6),
new Crockery("杯子", 10),
new Crockery("茶碟", 10),
new Crockery("马克杯", 6),
new Crockery("牛奶壶", 1)
});
}
}
}
C# 数据源的类定义
public class Crockery
{
public string Title { get; set; }
public int Number{ get; set; }
public Crockery(string title, int number)
{
Title = title;
Number = number;
}
}
视图水平方向可调整大小,但内容在过高时会被隐藏。这个控件没有内置滚动条(与 ListBox
不同)。
ItemsRepeater 元素重复器
元素重复器可以从绑定的数据源显示重复数据。它具有布局模板和数据模板。
信息
元素重复器是 UWP ItemsRepeater
控件的移植版本。更多信息请参见这里。
信息
元素重复器已移至这里。
默认的布局模板是垂直堆叠布局,因此元素会以垂直列表的形式显示。
示例
此示例将一个可观察的餐具项集合绑定到元素重复器控件,其中每个元素的自定义布局和格式由数据模板提供:
<StackPanel Margin="20">
<TextBlock Margin="0 5">餐具列表:</TextBlock>
<ItemsRepeater ItemsSource="{Binding CrockeryList}">
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Border Margin="0,10,0,0"
CornerRadius="5"
BorderBrush="Blue" BorderThickness="1"
Padding="5">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}"/>
<TextBlock Margin="5 0" FontWeight="Bold"
Text="{Binding Number}"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel>
C# ViewModel
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<Crockery> CrockeryList { get; set; }
public MainWindowViewModel()
{
CrockeryList = new ObservableCollection<Crockery>(new List<Crockery>
{
new Crockery("晚餐盘", 12),
new Crockery("小盘", 12),
new Crockery("早餐碗", 6),
new Crockery("杯子", 10),
new Crockery("茶托", 10),
new Crockery("马克杯", 6),
new Crockery("牛奶壶", 1)
});
}
}
}
C# 数据源的类定义
public class Crockery
{
public string Title { get; set; }
public int Number { get; set; }
public Crockery(string title, int number)
{
Title = title;
Number = number;
}
}
默认情况下,元素重复器将以垂直堆叠布局渲染元素。你可以通过使用 <ItemsRepeater.Layout>
元素覆盖此设置,使元素水平显示。例如:
<StackPanel Margin="20">
<TextBlock Margin="0 5">餐具列表:</TextBlock>
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<ItemsRepeater ItemsSource="{Binding CrockeryList}" Margin="0 20">
<ItemsRepeater.Layout>
<StackLayout Spacing="40"
Orientation="Horizontal" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Border Margin="0,10,0,0"
CornerRadius="5"
BorderBrush="Blue" BorderThickness="1"
Padding="5">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}"/>
<TextBlock Margin="5 0" FontWeight="Bold"
Text="{Binding Number}"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>
</StackPanel>
元素水平显示,如果没有添加围绕元素重复器的滚动查看器元素,那么过于靠右的元素将会被隐藏。