I'm new to WinUI3. I'm trying to create a modal dialog using ContentDialog class, but the async nature confuses me. Suppose, there is an WinUI3 application like shown below. I have two buttons which display the same ContentDialog one in modal the other in modeless way.
winrt::Windows::Foundation::IAsyncAction MainWindow::ShowAlert()
{
ContentDialog dlg;
dlg.XamlRoot(Content().XamlRoot());
dlg.Title(winrt::box_value(L"Title"));
dlg.Content(winrt::box_value(L"Message"));
dlg.PrimaryButtonText(L"OK");
dlg.SecondaryButtonText(L"Cancel");
ContentDialogResult res = co_await dlg.ShowAsync();
_value = (res == ContentDialogResult::Primary ? 1 : 2);
}
void MainWindow::button1Click(IInspectable const&, RoutedEventArgs const&)
{
_value = 0;
// modeless invocation
ShowAlert();
// label displays 0, always
label().Text(winrt::to_hstring(_value));
}
winrt::Windows::Foundation::IAsyncAction MainWindow::button2Click(IInspectable const&, RoutedEventArgs const&)
{
_value = 0;
// modal invocation
co_await ShowAlert();
// label displays either 1 or 2
label().Text(winrt::to_hstring(_value));
co_return;
}
I wonder if there is a way to display the dialog in modal way from the button1Click() handler which returns 'void'. The execution flow in that function will depend on the result of the invocation of modal dialog.
Adding co_await to ShowAlert in button1Click() call results in compiler error:
error C2039: 'promise_type': is not a member of 'std::experimental::coroutine_traits<void,winrt::App1::implementation::MainWindow *,const winrt::implements<D,winrt::App1::MainWindow,winrt::composing,winrt::Microsoft::UI::Xaml::Markup::IComponentConnector>::IInspectable &,const winrt::Microsoft::UI::Xaml::RoutedEventArgs &>'
Thanks in advance!
I don't see your definition for ShowAlert, but presumably the reason co_await does not work for it is that ShowAlert does not have the correct asynchronous return definition (promise_type). The underlying ContentDialog in WinUI only has one way to invoke it, which is ShowAsync i.e. an asynchronous invocation.
ContentDialog in particular has some funny things about it such as (a) only one can be shown at a time and (b) to force the location to be centered on the app, the content dialog must be part of the app's main UI rather than, for example, relative to the current page or relative to a control.
P.S. I would recommend that if at all possible you switch to C# as it has more structure for async operations, specifically for awaiting tasks vs iterators and for defining the task return types.