Files
AtomUI/docs/release-notes/6.0.8-api-changes.md
T
2026-07-10 07:31:20 +08:00

7.8 KiB
Raw Blame History

AtomUI 6.0.8 API 变更示例

本文档补充 6.0.8 相比 6.0.7 的主要 API 变更和迁移写法。正式版本条目见仓库根目录 CHANGELOG.md 和 CHANGELOG.zh-CN.md。

ImagePreviewer 图片源迁移

6.0.8 将 ImagePreviewer 的图片源统一到 IImagePreviewSource:

  • SourceUri -> Source
  • SourceUris -> Sources
  • FallbackSourceUri -> FallbackSource
  • URI、本地文件、Avalonia resource 使用 UriImagePreviewSource
  • 数据库、鉴权网络、加密文件、内存数据等按需流使用 StreamImagePreviewSource

6.0.7 写法

<atom:ImagePreviewer
    SourceUri="https://example.com/photo.jpg"
    FallbackSourceUri="avares://Demo/Assets/fallback.png" />

6.0.8 写法

using AtomUI.Desktop.Controls;

public IImagePreviewSource PreviewSource { get; } =
    new UriImagePreviewSource("https://example.com/photo.jpg");

public IImagePreviewSource PreviewFallbackSource { get; } =
    new UriImagePreviewSource("avares://Demo/Assets/fallback.png");
<atom:ImagePreviewer
    Source="{Binding PreviewSource}"
    FallbackSource="{Binding PreviewFallbackSource}" />

多图、封面和预加载

CoverIndex 只决定关闭态封面显示哪一张,不会改变 CurrentIndex。

public IList<IImagePreviewSource> PreviewImages { get; } =
[
    new UriImagePreviewSource("https://example.com/photo-1.jpg"),
    new UriImagePreviewSource("https://example.com/photo-2.jpg"),
    new UriImagePreviewSource("https://example.com/photo-3.jpg")
];

public int CurrentPreviewIndex { get; set; }
<atom:ImageGroupPreviewer
    Sources="{Binding PreviewImages}"
    CoverIndex="1"
    CurrentIndex="{Binding CurrentPreviewIndex}"
    MaxConcurrentLoads="4"
    PreloadCount="1" />

懒加载数据流

OpenReadAsync 每次调用都应返回新的可读流,返回流由 ImagePreviewer 负责释放。

public IImagePreviewSource SecurePreviewSource { get; } =
    new StreamImagePreviewSource(
        openReadAsync: cancellationToken =>
        {
            Stream stream = File.OpenRead("/secure/photos/invoice.png");
            return new ValueTask<Stream>(stream);
        },
        displayName: "invoice.png",
        contentType: "image/png",
        identity: "/secure/photos/invoice.png");

Upload 组合式触发器迁移

6.0.8 中 Upload 根控件只负责文件状态、队列、Form 值和生命周期;选择文件、选择目录、拖拽区由可组合控件承担。

6.0.7 写法

<atom:Upload
    IsUploadDirectoryEnabled="True"
    IsShowUploadTrigger="True"
    DefaultTaskList="{Binding DefaultTaskList}"
    UploadTransport="{Binding UploadTransport}" />

6.0.8 写法

using AtomUI.Desktop.Controls;
using System.Collections.ObjectModel;

public ObservableCollection<UploadFileItem> Attachments { get; } = [];

public IFileUploadTransport UploadTransport { get; } = new MyUploadTransport();
<atom:Upload
    Files="{Binding Attachments}"
    UploadTransport="{Binding UploadTransport}"
    AutoUpload="True"
    ListMaxHeight="180"
    ListScrollBarVisibility="Auto"
    SuccessAutoRemoveDelay="0:0:3">
    <atom:Space>
        <atom:UploadTrigger SourceKind="Files">
            <atom:Button Content="Select files" />
        </atom:UploadTrigger>
        <atom:UploadTrigger SourceKind="Directories">
            <atom:Button Content="Select directory" />
        </atom:UploadTrigger>
    </atom:Space>
</atom:Upload>

拖拽上传

<atom:Upload
    Files="{Binding Attachments}"
    UploadTransport="{Binding UploadTransport}">
    <atom:UploadDropZone>
        <TextBlock Text="Drop files here" />
    </atom:UploadDropZone>
</atom:Upload>

Form 值投影

FileValueMode 控制 Upload 写入 Form 的值:

<atom:Upload
    Files="{Binding Attachments}"
    FileValueMode="Results"
    UploadTransport="{Binding UploadTransport}" />

OtpLineEdit 新增控件

OtpLineEdit 用单一 Text 表达完整验证码;cell、separator 和 mask 只影响视觉。

<atom:OtpLineEdit
    Text="{Binding Code}"
    Length="6"
    InputMode="Numeric"
    Separator="-"
    SeparatorInterval="3"
    StyleVariant="Outlined" />
<atom:OtpLineEdit
    Text="{Binding RecoveryCode}"
    Length="8"
    InputMode="AlphaNumeric"
    IsMasked="True"
    PlaceholderText="•" />
public string? Code { get; set; }

Form 和 DataValidationErrors

6.0.8 中 Form validator 产生的错误会写入 Avalonia DataValidationErrors。如果已有 ViewModel 校验、binding 校验或业务层原生 validation error,AtomUI 控件会以原生 error 为最高优先级展示。

默认触发方式为 OnChanged;需要失焦后再验证时显式配置:

<atom:Form ValidateTrigger="OnBlur">
    <atom:FormItem Name="UserName" IsRequired="True">
        <atom:LineEdit Text="{Binding UserName}" />
    </atom:FormItem>
</atom:Form>

默认双向绑定

多个选择和值语义属性现在默认使用 BindingMode.TwoWay。不再需要在常规场景中显式写 Mode=TwoWay:

<atom:Select
    OptionsSource="{Binding CityOptions}"
    SelectedOption="{Binding SelectedCity}" />

<atom:TreeSelect
    ItemsSource="{Binding TreeNodes}"
    SelectedItems="{Binding SelectedTreeNodes}" />

<atom:DatePicker SelectedDateTime="{Binding SelectedDate}" />

<atom:TimePicker SelectedTime="{Binding SelectedTime}" />

<atom:Rate Value="{Binding Rating}" />

<atom:Dialog IsOpen="{Binding IsSettingsOpen}" />

如果业务确实需要只读投影,仍可在绑定上显式设置 Mode=OneWay。

DataGrid 过滤模型

列过滤现在直接挂在列 API 上,过滤项来源和选中值可绑定:

<atom:DataGridTextColumn
    Header="Name"
    Binding="{Binding Name}"
    Filters="{Binding NameFilters}"
    SelectedFilterValues="{Binding SelectedNames}"
    FilterTextMemberPath="Text"
    FilterValueMemberPath="Value"
    FilterPresenterMode="Menu"
    FilterSelectionMode="Multiple"
    FilterApplyMode="SelectionChanged" />

树形过滤使用 FilterChildrenMemberPath:

<atom:DataGridTextColumn
    Header="Department"
    Binding="{Binding Department}"
    Filters="{Binding DepartmentFilters}"
    SelectedFilterValues="{Binding SelectedDepartments}"
    FilterTextMemberPath="Name"
    FilterValueMemberPath="Id"
    FilterChildrenMemberPath="Children"
    FilterPresenterMode="Tree" />

Select、ComboBox 和 Cascader 溢出提示

选中内容无法完整显示时,可以开启溢出 tooltip:

<atom:Select
    IsShowOverflowTip="True"
    OverflowTipDelay="800"
    OverflowTipPlacement="TopEdgeAlignedLeft"
    OptionsSource="{Binding Options}"
    SelectedOptions="{Binding SelectedOptions}" />

<atom:ComboBox
    IsShowOverflowTip="True"
    OverflowTipDelay="800"
    OverflowTipPlacement="TopEdgeAlignedLeft"
    ItemsSource="{Binding Items}" />

TabControl 和 TabStrip 拖动排序

<atom:TabControl
    IsTabReorderEnabled="True"
    TabActivationTrigger="PointerReleased"
    TabReordering="HandleTabReordering"
    TabReordered="HandleTabReordered">
    <atom:TabItem Header="Tab 1">Content 1</atom:TabItem>
    <atom:TabItem Header="Tab 2">Content 2</atom:TabItem>
    <atom:TabItem Header="Tab 3">Content 3</atom:TabItem>
</atom:TabControl>

TabActivationTrigger="PointerReleased" 是默认值,适合拖动排序场景;如果需要鼠标按下立即激活,可改为 PointerPressed。

Dialog 异步关闭校验

await Dialog.ShowDialogAsync(
    new TextBlock { Text = "Close without saving?" },
    options: new DialogOptions
    {
        Title = "Unsaved changes",
        BeforeCloseAsync = async context =>
        {
            if (context.Reason == DialogCloseReason.Rejected)
            {
                return true;
            }

            return await ConfirmSaveAsync();
        }
    });