11 KiB
AtomUI 6.1.0 API Change Examples
This document supplements the main 6.1.0 release notes with the most important breaking API changes and migration examples from 6.0.8.
For the authoritative release entries, see the repository root CHANGELOG.md and CHANGELOG.zh-CN.md.
Chinese version: 6.1.0 API 变更示例.
Dialog and MessageBox Async Session Migration
6.1.0 unifies Dialog and MessageBox static display APIs, close requests, and host lifecycle around an async session model:
- Synchronous static APIs have been removed:
ShowDialog,ShowDialogModal, andShowMessageBox. - Async static APIs with a
closedcallback have been removed. - External host extension points have been removed:
IDialogHostandIDialogHostProvider. - Result wrapper interfaces have been removed:
IDialogActionResultandIMessageBoxActionResult. - Static APIs now return
Task<object?>; read the close result from the awaited result directly. - Close validation now uses
BeforeCloseAsyncconsistently.
Synchronous Static Dialog Calls
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-Style Dialog Close Results
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();
}
Opening Dialog Instances
When creating a Dialog or MessageBox instance directly, migrate synchronous Open() calls to async OpenAsync().
Read the close result from the instance Result property.
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 Static API Names and Results
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();
}
Modal MessageBox also uses the full method name:
object? result = await MessageBox.ShowMessageBoxModalAsync(
new DeleteConfirmView(),
dataContext,
new MessageBoxOptions
{
Title = "Delete item",
Style = MessageBoxStyle.Warning
},
topLevel);
Close Validation
BeforeCloseAsync is now the unified validation entry point for Dialog and MessageBox close requests.
Return false to reject the close request; return true to allow it.
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);
Custom Dialog Hosts
If a project implemented IDialogHost or IDialogHostProvider to take over overlay hosts, 6.1.0 no longer supports that extension path.
Prefer the built-in host selection and placement configuration:
object? result = await Dialog.ShowDialogAsync(
new DetailsDialogView(),
viewModel,
new DialogOptions
{
DialogHostType = DialogHostType.Overlay,
PlacementTarget = ownerPanel,
HostWidth = 520,
HostMinHeight = 240
},
topLevel);
Choose DialogHostType.Window explicitly when a separate window host is required:
object? result = await Dialog.ShowDialogModalAsync(
new ReportDialogView(),
viewModel,
new DialogOptions
{
DialogHostType = DialogHostType.Window,
Title = "Report"
},
topLevel);
Steps Controlled State Migration
6.1.0 changes Steps from SelectingItemsControl to ItemsControl.
Public state is now expressed through Current, Initial, Status, Percent, Type, and TitlePlacement.
API Reference
| 6.0.8 API | 6.1.0 API | Notes |
|---|---|---|
CurrentStep |
Current |
Current step number |
InitialStep |
Initial |
Number offset for the first step |
CurrentStepStatus |
Status |
Current step status |
StepsItemStatus |
StepsStatus |
Status enum rename |
StepsStyle + StepsItemIndicatorType |
StepsType |
Style and indicator type merged |
LabelPlacement |
TitlePlacement |
Title layout placement |
ProgressValue + IsShowItemProgress |
Percent |
Nullable progress value; null hides progress |
SelectedIndex / SelectedItem |
Current + CurrentChangeRequested |
Selection state is no longer used |
CurrentContent / CurrentContentTemplate |
Project from application ViewModel | Steps no longer owns a current-item content outlet |
StepsItem.Description / DescriptionTemplate |
StepsItem.Content / ContentTemplate |
Step details now use the standard Content contract |
Basic XAML Property Migration
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}" />
If old markup used Style="Navigation" or Style="Inline", migrate directly to Type="Navigation" or Type="Inline".
If old markup used the default style with ItemIndicatorType="Default", omit Type or set Type="Default".
Clickable Steps
CurrentChangeRequested means “the user requested a step change.”
The control does not mutate Current directly on click; application code confirms that the transition is allowed, then updates the bound 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;
}
}
Step Item Description Content
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>
Use ContentTemplate for richer description content:
<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>
Current Step Content Projection
CurrentContent and CurrentContentTemplate have been removed.
When a page needs to show the current step content outside Steps, project it from the ViewModel based on 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));
}
Explicit Step Status
StepsItem.Status is now nullable.
When it is not set, Steps derives the automatic status from Current, Initial, and the root Status.
Set it only when overriding a specific step:
<atom:Steps Current="{Binding CurrentStep}" Status="Process">
<atom:StepsItem Header="Create" />
<atom:StepsItem Header="Review" Status="Error" />
<atom:StepsItem Header="Publish" />
</atom:Steps>
This pins only Review to Error; the other steps continue to use automatic status.