Files
AtomUI/docs/release-notes/6.1.0-api-changes.md
T

11 KiB
Raw Blame History

AtomUI 6.1.0 API 变更示例

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

Dialog 和 MessageBox 异步会话迁移

6.1.0 将 Dialog 和 MessageBox 的静态展示、关闭请求和宿主生命周期统一到异步 Session 模型:

  • 移除同步静态 API:ShowDialog、ShowDialogModal、ShowMessageBox。
  • 移除带 closed callback 的异步静态 API。
  • 移除外部宿主扩展点:IDialogHost、IDialogHostProvider。
  • 移除结果包装接口:IDialogActionResult、IMessageBoxActionResult。
  • 静态 API 统一返回 Task<object?>,关闭结果直接从 await 结果获得。
  • 关闭前校验统一使用 BeforeCloseAsync。

同步静态 Dialog 调用

6.0.8 写法

object? result = Dialog.ShowDialog<SettingsDialogView, SettingsDialogViewModel>(
    viewModel,
    new DialogOptions
    {
        Title           = "Settings",
        StandardButtons = DialogStandardButton.Ok | DialogStandardButton.Cancel
    },
    topLevel);

if (result is DialogCode.Accepted)
{
    SaveSettings();
}

6.1.0 写法

object? result = await Dialog.ShowDialogAsync<SettingsDialogView, SettingsDialogViewModel>(
    viewModel,
    new DialogOptions
    {
        Title           = "Settings",
        StandardButtons = DialogStandardButton.Ok | DialogStandardButton.Cancel
    },
    topLevel);

if (result is DialogCode.Accepted)
{
    SaveSettings();
}

callback 式 Dialog 关闭结果

6.0.8 写法

await Dialog.ShowDialogAsync(
    new SettingsDialogView(),
    viewModel,
    new DialogOptions
    {
        Title           = "Settings",
        StandardButtons = DialogStandardButton.Ok | DialogStandardButton.Cancel
    },
    closed: actionResult =>
    {
        if (actionResult.Result is DialogCode.Accepted)
        {
            SaveSettings();
        }
    },
    topLevel);

6.1.0 写法

object? result = await Dialog.ShowDialogAsync(
    new SettingsDialogView(),
    viewModel,
    new DialogOptions
    {
        Title           = "Settings",
        StandardButtons = DialogStandardButton.Ok | DialogStandardButton.Cancel
    },
    topLevel);

if (result is DialogCode.Accepted)
{
    SaveSettings();
}

实例 Dialog 打开

直接创建 Dialog 或 MessageBox 实例时,同步 Open() 也需要迁移到异步 OpenAsync()。关闭结果从实例的 Result 属性读取。

6.0.8 写法

var dialog = new Dialog
{
    Title           = "Settings",
    Content         = new SettingsDialogView(),
    DataContext     = viewModel,
    StandardButtons = DialogStandardButton.Ok | DialogStandardButton.Cancel
};

object? result = dialog.Open();

if (result is DialogCode.Accepted)
{
    SaveSettings();
}

6.1.0 写法

var dialog = new Dialog
{
    Title           = "Settings",
    Content         = new SettingsDialogView(),
    DataContext     = viewModel,
    StandardButtons = DialogStandardButton.Ok | DialogStandardButton.Cancel
};

await dialog.OpenAsync();
object? result = dialog.Result;

if (result is DialogCode.Accepted)
{
    SaveSettings();
}

MessageBox 静态 API 命名和结果

6.0.8 写法

await MessageBox.ShowMessageAsync(
    new DeleteConfirmView(),
    dataContext,
    new MessageBoxOptions
    {
        Title = "Delete item",
        Style = MessageBoxStyle.Confirm
    },
    closed: actionResult =>
    {
        if (actionResult.Result is DialogCode.Accepted)
        {
            DeleteItem();
        }
    },
    topLevel);

6.1.0 写法

object? result = await MessageBox.ShowMessageBoxAsync(
    new DeleteConfirmView(),
    dataContext,
    new MessageBoxOptions
    {
        Title = "Delete item",
        Style = MessageBoxStyle.Confirm
    },
    topLevel);

if (result is DialogCode.Accepted)
{
    DeleteItem();
}

模态 MessageBox 同样使用完整命名:

object? result = await MessageBox.ShowMessageBoxModalAsync(
    new DeleteConfirmView(),
    dataContext,
    new MessageBoxOptions
    {
        Title = "Delete item",
        Style = MessageBoxStyle.Warning
    },
    topLevel);

关闭前校验

BeforeCloseAsync 现在是 Dialog 和 MessageBox 关闭请求的统一校验入口。返回 false 表示拒绝本次关闭; 返回 true 表示允许关闭。

object? result = await Dialog.ShowDialogAsync(
    new EditProfileView(),
    viewModel,
    new DialogOptions
    {
        Title           = "Edit profile",
        StandardButtons = DialogStandardButton.Ok | DialogStandardButton.Cancel,
        BeforeCloseAsync = async context =>
        {
            if (context.DialogCode is DialogCode.Accepted)
            {
                return await viewModel.ValidateAndSaveAsync(context.CancellationToken);
            }

            return true;
        }
    },
    topLevel);

自定义 Dialog 宿主

如果项目实现了 IDialogHost 或 IDialogHostProvider 来接管 overlay 宿主,6.1.0 不再支持这条扩展路径。 优先迁移到内置 host 选择和 placement 配置:

object? result = await Dialog.ShowDialogAsync(
    new DetailsDialogView(),
    viewModel,
    new DialogOptions
    {
        DialogHostType  = DialogHostType.Overlay,
        PlacementTarget = ownerPanel,
        HostWidth       = 520,
        HostMinHeight   = 240
    },
    topLevel);

需要独立窗口宿主时显式选择 DialogHostType.Window:

object? result = await Dialog.ShowDialogModalAsync(
    new ReportDialogView(),
    viewModel,
    new DialogOptions
    {
        DialogHostType = DialogHostType.Window,
        Title          = "Report"
    },
    topLevel);

Steps 受控状态迁移

6.1.0 将 Steps 从 SelectingItemsControl 改为 ItemsControl,公共状态围绕 Current、Initial、Status、 Percent、Type 和 TitlePlacement 表达。

API 对照

6.0.8 API 6.1.0 API 说明
CurrentStep Current 当前步骤编号
InitialStep Initial 第一个步骤的编号偏移
CurrentStepStatus Status 当前步骤状态
StepsItemStatus StepsStatus 状态枚举重命名
StepsStyle + StepsItemIndicatorType StepsType 样式和指示器类型合并
LabelPlacement TitlePlacement 标题布局位置
ProgressValue + IsShowItemProgress Percent 可空进度值;null 表示不显示进度
SelectedIndex / SelectedItem Current + CurrentChangeRequested 不再使用 Selection 状态
CurrentContent / CurrentContentTemplate 业务 ViewModel 自行投影 Steps 不再维护当前项内容出口
StepsItem.Description / DescriptionTemplate StepsItem.Content / ContentTemplate 步骤详情改用标准 Content 契约

基础 XAML 属性迁移

6.0.8 写法

<atom:Steps
    CurrentStep="{Binding CurrentStep}"
    InitialStep="1"
    CurrentStepStatus="Process"
    Style="Default"
    ItemIndicatorType="Dot"
    LabelPlacement="Vertical"
    IsShowItemProgress="True"
    ProgressValue="{Binding ProgressValue}" />

6.1.0 写法

<atom:Steps
    Current="{Binding CurrentStep}"
    Initial="1"
    Status="Process"
    Type="Dot"
    TitlePlacement="Vertical"
    Percent="{Binding ProgressValue}" />

如果旧写法使用 Style="Navigation" 或 Style="Inline",直接迁移到 Type="Navigation" 或 Type="Inline"。 如果旧写法是默认样式加 ItemIndicatorType="Default",可以省略 Type 或写 Type="Default"。

可点击步骤

CurrentChangeRequested 是“用户请求切换步骤”的事件。控件不会在点击时直接修改 Current;业务代码确认允许 切换后,再更新绑定的 Current。

6.0.8 写法

<atom:Steps
    CurrentStep="{Binding CurrentStep}"
    IsItemClickable="True" />

6.1.0 写法

<atom:Steps
    Current="{Binding CurrentStep}"
    IsItemClickable="True"
    CurrentChangeRequested="HandleCurrentChangeRequested" />
private void HandleCurrentChangeRequested(
    object? sender,
    StepsCurrentChangeRequestedEventArgs e)
{
    if (ViewModel.CanMoveTo(e.Current))
    {
        ViewModel.CurrentStep = e.Current;
    }
}

步骤项描述内容

6.0.8 写法

<atom:Steps>
    <atom:StepsItem
        Header="Login"
        Description="Sign in with your account" />
    <atom:StepsItem
        Header="Verify"
        Description="Enter the verification code" />
</atom:Steps>

6.1.0 写法

<atom:Steps>
    <atom:StepsItem Header="Login">
        Sign in with your account
    </atom:StepsItem>
    <atom:StepsItem Header="Verify">
        Enter the verification code
    </atom:StepsItem>
</atom:Steps>

复杂描述内容使用 ContentTemplate:

<atom:StepsItem Header="Verify" Content="{Binding VerifyStep}">
    <atom:StepsItem.ContentTemplate>
        <DataTemplate>
            <atom:Space Orientation="Vertical" Spacing="4">
                <TextBlock Text="{Binding Summary}" />
                <TextBlock Text="{Binding HelpText}" />
            </atom:Space>
        </DataTemplate>
    </atom:StepsItem.ContentTemplate>
</atom:StepsItem>

当前步骤内容投影

CurrentContent 和 CurrentContentTemplate 已移除。需要在 Steps 外部展示当前步骤页面时,由 ViewModel 根据 Current 投影当前内容。

6.0.8 写法

<atom:Steps
    x:Name="WizardSteps"
    CurrentStep="{Binding CurrentStep}"
    ContentTemplate="{StaticResource WizardStepTemplate}" />

<ContentControl
    Content="{Binding #WizardSteps.CurrentContent}"
    ContentTemplate="{Binding #WizardSteps.CurrentContentTemplate}" />

6.1.0 写法

<atom:Steps
    Current="{Binding CurrentStep}"
    CurrentChangeRequested="HandleCurrentChangeRequested" />

<ContentControl
    Content="{Binding CurrentStepContent}"
    ContentTemplate="{StaticResource WizardStepTemplate}" />
public object? CurrentStepContent => Steps.FirstOrDefault(step => step.Number == CurrentStep);

private void HandleCurrentChangeRequested(
    object? sender,
    StepsCurrentChangeRequestedEventArgs e)
{
    CurrentStep = e.Current;
    RaisePropertyChanged(nameof(CurrentStepContent));
}

显式步骤状态

StepsItem.Status 现在是可空状态。未设置时使用 Steps 根据 Current、Initial 和根 Status 推导出的自动状态; 需要覆盖单个步骤时再显式设置:

<atom:Steps Current="{Binding CurrentStep}" Status="Process">
    <atom:StepsItem Header="Create" />
    <atom:StepsItem Header="Review" Status="Error" />
    <atom:StepsItem Header="Publish" />
</atom:Steps>

这会只把 Review 固定为 Error,其他步骤继续使用自动状态。