mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-19 06:58:57 +08:00
11 KiB
11 KiB
Dialog 使用文档
本文档介绍 AtomUI Dialog 控件的各种使用方式,示例代码摘自 Gallery 演示程序。
📖 Gallery 源码位置:
controlgallery/AtomUIGallery/ShowCases/Views/Feedback/ModalShowCase.axaml
前置准备
在 AXAML 中使用 Dialog,需要引入以下命名空间:
xmlns:atom="https://atomui.net"
在 C# 代码中引入:
using AtomUI.Desktop.Controls; // Dialog, DialogOptions, DialogButton 等
1. 基础模态对话框
Overlay 模式(默认)
Dialog 声明在一个 Panel 中,通过 IsOpen 属性控制显示:
<Panel>
<atom:Button ButtonType="Primary" Name="OpenModalButton">
Open Modal Overlay
</atom:Button>
<atom:Dialog PlacementTarget="OpenModalButton"
IsOpen="{Binding IsModalOpened, Mode=TwoWay}"
Title="Basic Modal"
IsModal="True"
IsDragMovable="True"
StandardButtons="Cancel,Ok"
DefaultStandardButton="Ok"
HorizontalStartupLocation="Center"
VerticalOffset="30%"
MinWidth="300">
<StackPanel Orientation="Vertical">
<TextBlock>Some contents...</TextBlock>
<TextBlock>Some contents...</TextBlock>
<TextBlock>Some contents...</TextBlock>
</StackPanel>
</atom:Dialog>
</Panel>
// Code-behind:点击按钮打开
private void HandleOpenButtonClick(object? sender, RoutedEventArgs e)
{
if (DataContext is MyViewModel vm)
{
vm.IsModalOpened = true;
}
}
Window 模式
使用 DialogHostType="Window" 创建独立窗口对话框:
<atom:Dialog PlacementTarget="OpenWindowButton"
IsOpen="{Binding IsWindowModalOpened, Mode=TwoWay}"
Title="Basic Window Modal"
IsModal="True"
DialogHostType="Window"
IsClosable="True"
IsDragMovable="True"
IsMaximizable="False"
StandardButtons="Yes"
DefaultStandardButton="Yes"
MinWidth="300">
<StackPanel Orientation="Vertical">
<TextBlock>Some contents...</TextBlock>
</StackPanel>
</atom:Dialog>
2. 异步关闭
点击确认按钮后执行异步操作,完成后再关闭对话框。关键是通过 ButtonClicked 事件拦截并设置 IsConfirmLoading:
<atom:Dialog Title="Asynchronously close Modal"
IsModal="True"
IsDragMovable="True"
IsLightDismissEnabled="True"
StandardButtons="Ok, Cancel"
DefaultStandardButton="Ok"
ButtonClicked="HandleAsyncDialogButtonClicked"
MinWidth="400">
<TextBlock>Content of the modal</TextBlock>
</atom:Dialog>
private void HandleAsyncDialogButtonClicked(object? sender, DialogButtonClickedEventArgs e)
{
if (sender is Dialog dialog && e.SourceButton.Role == DialogButtonRole.AcceptRole)
{
dialog.IsConfirmLoading = true;
e.Handled = true; // 阻止默认的 Accept 行为
DispatcherTimer.RunOnce(() =>
{
dialog.IsConfirmLoading = false;
dialog.Done(); // 异步操作完成后手动关闭
}, TimeSpan.FromMilliseconds(3000));
}
}
要点:
e.Handled = true阻止了按钮的默认 Accept/Reject 行为;IsConfirmLoading = true阻止了对话框被其他方式关闭。
3. 加载状态
对话框可以在打开时处于加载状态,适用于需要加载数据的场景:
<atom:Dialog Title="Loading Modal"
IsModal="True"
IsLoading="True"
StandardButtons="Reload"
DefaultStandardButton="Reload"
Opened="HandleLoadingDialogOpened"
ButtonClicked="HandleLoadingDialogButtonClicked"
MinWidth="400">
<StackPanel>
<TextBlock>Some contents...</TextBlock>
</StackPanel>
</atom:Dialog>
// 打开后 3 秒自动结束加载
private void HandleLoadingDialogOpened(object? sender, EventArgs e)
{
if (sender is Dialog dialog)
{
DispatcherTimer.RunOnce(() => dialog.IsLoading = false,
TimeSpan.FromMilliseconds(3000));
}
}
// 点击 Reload 按钮重新加载
private void HandleLoadingDialogButtonClicked(object? sender, DialogButtonClickedEventArgs e)
{
if (sender is Dialog dialog)
{
dialog.IsLoading = true;
DispatcherTimer.RunOnce(() => dialog.IsLoading = false,
TimeSpan.FromMilliseconds(3000));
}
}
4. 自定义底部按钮
标准按钮 + 自定义按钮
<atom:Dialog Title="Title"
StandardButtons="Ok, Cancel"
DefaultStandardButton="Ok">
<atom:Dialog.CustomButtons>
<atom:DialogButton Role="ActionRole">Custom Button</atom:DialogButton>
</atom:Dialog.CustomButtons>
<StackPanel Spacing="5">
<TextBlock>Some contents...</TextBlock>
<TextBlock>Some contents...</TextBlock>
</StackPanel>
</atom:Dialog>
配置按钮属性
通过 ButtonsConfigure 回调可以在按钮创建后统一修改其属性:
// Code-behind
dialog.ButtonsConfigure = buttons =>
{
foreach (var button in buttons)
{
button.IsEnabled = false; // 例如:禁用所有按钮
}
};
5. 可拖拽对话框
<atom:Dialog Title="Draggable Modal"
IsModal="True"
IsDragMovable="True"
IsLightDismissEnabled="True"
StandardButtons="Ok, Cancel"
HorizontalStartupLocation="Center"
VerticalStartupLocation="Center"
Width="400">
<StackPanel Spacing="10">
<TextBlock TextWrapping="Wrap">
Just don't learn physics at school and your life will be full of magic and miracles.
</TextBlock>
</StackPanel>
</atom:Dialog>
6. 静态 API
Overlay 模态对话框
var content = new StackPanel { Orientation = Orientation.Vertical, Spacing = 5 };
content.Children.Add(new TextBlock { Text = "Some contents..." });
var options = new DialogOptions
{
Title = "Basic Modal",
IsResizable = false,
IsDragMovable = true,
IsMaximizable = false,
StandardButtons = DialogStandardButtons.Parse("Cancel,Ok"),
DefaultStandardButton = DialogStandardButton.Ok,
HorizontalStartupLocation = DialogHorizontalAnchor.Center,
VerticalOffset = new Dimension(30, DimensionUnitType.Percentage),
MinWidth = 400
};
await Dialog.ShowDialogModalAsync(content, null, options);
Window 模态对话框
var options = new DialogOptions
{
Title = "Window Modal",
DialogHostType = DialogHostType.Window,
IsResizable = false,
IsDragMovable = true,
StandardButtons = DialogStandardButtons.Parse("Cancel,Ok"),
DefaultStandardButton = DialogStandardButton.Ok,
HorizontalStartupLocation = DialogHorizontalAnchor.Center,
VerticalOffset = new Dimension(30, DimensionUnitType.Percentage),
MinWidth = 400
};
await Dialog.ShowDialogModalAsync(content, null, options);
自定义视图 + ViewModel
var viewModel = new MyViewModel { Name = "AtomUI", Age = 2 };
var options = new DialogOptions
{
Title = "Custom View Dialog",
DialogHostType = DialogHostType.Window,
StandardButtons = DialogStandardButtons.Parse("Cancel,Ok"),
DefaultStandardButton = DialogStandardButton.Ok,
HorizontalStartupLocation = DialogHorizontalAnchor.Center,
MinWidth = 400
};
await Dialog.ShowDialogModalAsync<MyView, MyViewModel>(viewModel, options);
非模态异步对话框(带关闭回调)
对于非模态对话框,ShowDialogAsync 提供 closed 回调参数,在对话框关闭时调用:
var content = new StackPanel();
content.Children.Add(new TextBlock { Text = "Non-modal dialog content" });
var options = new DialogOptions
{
Title = "Non-Modal",
StandardButtons = DialogStandardButtons.Parse("Ok,Cancel"),
HorizontalStartupLocation = DialogHorizontalAnchor.Center,
VerticalOffset = new Dimension(30, DimensionUnitType.Percentage),
MinWidth = 400
};
// ShowDialogAsync 在对话框显示后立即返回
// 通过 closed 回调获取结果
await Dialog.ShowDialogAsync(content, null, options, result =>
{
// result.Result 可能是 DialogCode.Accepted / DialogCode.Rejected / null
if (result.Result is DialogCode code && code == DialogCode.Accepted)
{
// 处理确认逻辑
}
});
注意:
ShowDialogAsync(非 Modal)的 Task 在对话框显示后就完成,await之后无法直接读取Result。需要通过Action<IDialogActionResult>? closed回调处理关闭逻辑。
7. MVVM 集成(IDialogAwareDataContext)
ViewModel 实现 IDialogAwareDataContext 接口后,可以在 ViewModel 层感知和控制对话框:
public class MyDialogViewModel : ReactiveObject, IDialogAwareDataContext
{
private IDialog? _dialog;
public void NotifyAttachedToDialog(IDialog dialog)
{
_dialog = dialog;
}
public void NotifyClosed()
{
// 对话框关闭时的清理逻辑
}
// ViewModel 中主动关闭对话框
public void ConfirmAndClose()
{
_dialog?.Accept();
}
public void CancelAndClose()
{
_dialog?.Reject();
}
}
常见组合模式
确认操作对话框
<atom:Dialog Title="确认删除"
IsModal="True"
StandardButtons="Ok, Cancel"
DefaultStandardButton="Ok"
HorizontalStartupLocation="Center"
VerticalStartupLocation="Center">
<TextBlock>确���要删除选中的项目吗?此操作不可撤销。</TextBlock>
</atom:Dialog>
表单对话框
<atom:Dialog Title="新建用户"
IsModal="True"
IsDragMovable="True"
StandardButtons="Save, Cancel"
DefaultStandardButton="Save"
Width="500"
HorizontalStartupLocation="Center"
VerticalOffset="20%">
<StackPanel Spacing="10">
<atom:TextBox Watermark="用户名" />
<atom:TextBox Watermark="邮箱" />
</StackPanel>
</atom:Dialog>
非模态工具窗口
<atom:Dialog Title="属性面板"
IsModal="False"
IsClosable="True"
IsDragMovable="True"
IsResizable="True"
IsFooterVisible="False"
Width="300"
Height="400">
<!-- 工具面板内容 -->
</atom:Dialog>