From da38a7098ff35e3109e1b11e08957efd9c01dec1 Mon Sep 17 00:00:00 2001 From: FF69B4 <78807100@qq.com> Date: Sat, 3 Jan 2026 21:39:40 +0800 Subject: [PATCH 1/3] Add WindowedContentDialog --- WinUI3Package/ContentDialogContent.cpp | 541 ++++++++++++ WinUI3Package/ContentDialogContent.h | 169 ++++ WinUI3Package/ContentDialogContent.idl | 60 ++ .../ContentDialogContent_Resource.xaml | 282 +++++++ WinUI3Package/ContentDialogUtils.h | 80 ++ WinUI3Package/ContentDialogWindow.idl | 79 ++ WinUI3Package/ContentDialogWindow.xaml | 36 + WinUI3Package/ContentDialogWindow.xaml.cpp | 798 ++++++++++++++++++ WinUI3Package/ContentDialogWindow.xaml.h | 234 +++++ ...ontentDialogWindowButtonClickEventArgs.cpp | 34 + .../ContentDialogWindowButtonClickEventArgs.h | 30 + ...ontentDialogWindowButtonClickEventArgs.idl | 17 + WinUI3Package/Underlay.idl | 24 + WinUI3Package/UnderlaySmokeLayerOptions.cpp | 19 + WinUI3Package/UnderlaySmokeLayerOptions.h | 24 + WinUI3Package/UnderlaySmokeLayerOptions.idl | 15 + .../UnderlaySystemBackdropOptions.cpp | 18 + WinUI3Package/UnderlaySystemBackdropOptions.h | 24 + .../UnderlaySystemBackdropOptions.idl | 14 + WinUI3Package/WinUI3Package.vcxproj | 85 ++ WinUI3Package/WinUI3Package.vcxproj.filters | 40 +- WinUI3Package/WinUIAsyncEventArgs.cpp | 20 + WinUI3Package/WinUIAsyncEventArgs.h | 28 + WinUI3Package/WinUIAsyncEventArgs.idl | 13 + WinUI3Package/WindowedContentDialog.cpp | 611 ++++++++++++++ WinUI3Package/WindowedContentDialog.h | 240 ++++++ WinUI3Package/WindowedContentDialog.idl | 77 ++ WinUI3Package/include/cppwinrt_utils.h | 58 ++ 28 files changed, 3665 insertions(+), 5 deletions(-) create mode 100644 WinUI3Package/ContentDialogContent.cpp create mode 100644 WinUI3Package/ContentDialogContent.h create mode 100644 WinUI3Package/ContentDialogContent.idl create mode 100644 WinUI3Package/ContentDialogContent_Resource.xaml create mode 100644 WinUI3Package/ContentDialogUtils.h create mode 100644 WinUI3Package/ContentDialogWindow.idl create mode 100644 WinUI3Package/ContentDialogWindow.xaml create mode 100644 WinUI3Package/ContentDialogWindow.xaml.cpp create mode 100644 WinUI3Package/ContentDialogWindow.xaml.h create mode 100644 WinUI3Package/ContentDialogWindowButtonClickEventArgs.cpp create mode 100644 WinUI3Package/ContentDialogWindowButtonClickEventArgs.h create mode 100644 WinUI3Package/ContentDialogWindowButtonClickEventArgs.idl create mode 100644 WinUI3Package/Underlay.idl create mode 100644 WinUI3Package/UnderlaySmokeLayerOptions.cpp create mode 100644 WinUI3Package/UnderlaySmokeLayerOptions.h create mode 100644 WinUI3Package/UnderlaySmokeLayerOptions.idl create mode 100644 WinUI3Package/UnderlaySystemBackdropOptions.cpp create mode 100644 WinUI3Package/UnderlaySystemBackdropOptions.h create mode 100644 WinUI3Package/UnderlaySystemBackdropOptions.idl create mode 100644 WinUI3Package/WinUIAsyncEventArgs.cpp create mode 100644 WinUI3Package/WinUIAsyncEventArgs.h create mode 100644 WinUI3Package/WinUIAsyncEventArgs.idl create mode 100644 WinUI3Package/WindowedContentDialog.cpp create mode 100644 WinUI3Package/WindowedContentDialog.h create mode 100644 WinUI3Package/WindowedContentDialog.idl create mode 100644 WinUI3Package/include/cppwinrt_utils.h diff --git a/WinUI3Package/ContentDialogContent.cpp b/WinUI3Package/ContentDialogContent.cpp new file mode 100644 index 0000000..f4a11ca --- /dev/null +++ b/WinUI3Package/ContentDialogContent.cpp @@ -0,0 +1,541 @@ +#include "pch.h" +#include "ContentDialogContent.h" +#if __has_include("ContentDialogContent.g.cpp") +#include "ContentDialogContent.g.cpp" +#endif + +#include + +#include "include/ScopedButtonDisabler.hpp" +#include "ContentDialogWindowButtonClickEventArgs.h" + +#include "ContentDialogUtils.h" + +namespace winrt::WinUI3Package::implementation +{ + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_TitleProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"Title", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ winrt::box_value(L"") }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_TitleTemplateProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"TitleTemplate", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ nullptr }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_PrimaryButtonTextProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"PrimaryButtonText", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ winrt::box_value(L""), OnButtonTextChangedStatic }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_SecondaryButtonTextProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"SecondaryButtonText", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ winrt::box_value(L""), OnButtonTextChangedStatic }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_CloseButtonTextProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"CloseButtonText", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ winrt::box_value(L""), OnButtonTextChangedStatic }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_IsPrimaryButtonEnabledProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"IsPrimaryButtonEnabled", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ box_value(true), nullptr }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_IsSecondaryButtonEnabledProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"IsSecondaryButtonEnabled", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ box_value(true), nullptr }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_DefaultButtonProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"DefaultButton", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ winrt::box_value(Microsoft::UI::Xaml::Controls::ContentDialogButton::Close), OnDefaultButtonChangedStatic }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_PrimaryButtonStyleProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"PrimaryButtonStyle", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ nullptr }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_SecondaryButtonStyleProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"SecondaryButtonStyle", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ nullptr }); + + winrt::Microsoft::UI::Xaml::DependencyProperty ContentDialogContent::_CloseButtonStyleProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::Register( + L"CloseButtonStyle", + xaml_typename(), + xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ nullptr }); + + + ContentDialogContent::ContentDialogContent() { + + DefaultStyleKey(box_value(winrt::xaml_typename())); + + isCustomMeasureFinishedAfterLoaded = false; + + PrimaryButtonStyle(ContentDialogUtils::DefaultButtonStyle()); + SecondaryButtonStyle(ContentDialogUtils::DefaultButtonStyle()); + CloseButtonStyle(ContentDialogUtils::DefaultButtonStyle()); + + IsPrimaryButtonEnabled(true); + IsSecondaryButtonEnabled(true); + + Loaded([this](auto&, auto&) { + + buttonsVisibilityState = DetermineButtonsVisibilityState(); + defaultButtonState = DetermineDefaultButtonState(); + + if (IsHeaderImage()) { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"CommandSpaceExpanded", false); + } + + }); + + m_OnUnloaded = Unloaded([this](auto&, auto&) { + + + isCustomMeasureFinishedAfterLoaded = false; + + }); + + RightTapped({ this,&ContentDialogContent::m_ContentRightTapped }); + + + m_PrimaryButtonKeyboardAccelerators = (winrt::single_threaded_vector()); + m_SecondaryButtonKeyboardAccelerators = (winrt::single_threaded_vector()); + m_CloseButtonKeyboardAccelerators = (winrt::single_threaded_vector()); + + //VerticalAlignment(Microsoft::UI::Xaml::VerticalAlignment::Center); + //HorizontalAlignment(Microsoft::UI::Xaml::HorizontalAlignment::Center); + + //m_CommandSpace = { nullptr }; + //PrimaryButton = { nullptr }; + //SecondaryButton = { nullptr }; + //CloseButton = { nullptr }; + //m_TitleArea = {nullptr}; + + } + + ContentDialogContent::~ContentDialogContent() { + + Unloaded(m_OnUnloaded); + + PrimaryButton.Click(m_OnPrimaryButtonClick); + SecondaryButton.Click(m_OnSecondaryButtonClick); + CloseButton.Click(m_OnCloseButtonClick); + } + + void ContentDialogContent::OnApplyTemplate() + { + Super::OnApplyTemplate(); + + TitleArea(GetTemplateChild(L"TitleArea").try_as()); + DialogSpace(GetTemplateChild(L"DialogSpace").try_as()); + CommandSpace(GetTemplateChild(L"CommandSpace").try_as()); + + PrimaryButton = GetTemplateChild(L"PrimaryButton").try_as(); + SecondaryButton = GetTemplateChild(L"SecondaryButton").try_as(); + CloseButton = GetTemplateChild(L"CloseButton").try_as(); + + if (IsHeaderImage()) { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"CommandSpaceExpanded", false); + } + + m_OnPrimaryButtonClick = PrimaryButton.Click([&](winrt::Windows::Foundation::IInspectable const& sender, auto&)->winrt::Windows::Foundation::IAsyncAction { + + ScopedButtonDisabler disabler{ sender, true }; + + auto ContentDialogArgs = WinUI3Package::ContentDialogWindowButtonClickEventArgs(); + + m_PrimaryButtonClick(*this, ContentDialogArgs); + + co_await ContentDialogArgs.wait_for_deferrals(); + + }); + + m_OnSecondaryButtonClick = SecondaryButton.Click([&](auto const& sender, auto&)->winrt::Windows::Foundation::IAsyncAction { + + ScopedButtonDisabler disabler{ sender, true }; + + auto ContentDialogArgs = WinUI3Package::ContentDialogWindowButtonClickEventArgs(); + + m_SecondaryButtonClick(*this, ContentDialogArgs); + + co_await ContentDialogArgs.wait_for_deferrals(); + }); + + m_OnCloseButtonClick = CloseButton.Click([&](auto const& sender, auto&)->winrt::Windows::Foundation::IAsyncAction { + + ScopedButtonDisabler disabler{ sender, true }; + auto ContentDialogArgs = WinUI3Package::ContentDialogWindowButtonClickEventArgs(); + m_CloseButtonClick(*this, ContentDialogArgs); + + co_await ContentDialogArgs.wait_for_deferrals(); + }); + + for (const auto& keyboardAccelerator : PrimaryButtonKeyboardAccelerators()) { + + PrimaryButton.KeyboardAccelerators().Append(keyboardAccelerator); + } + + for (const auto& keyboardAccelerator : SecondaryButtonKeyboardAccelerators()) { + + SecondaryButton.KeyboardAccelerators().Append(keyboardAccelerator); + } + + for (const auto& keyboardAccelerator : CloseButtonKeyboardAccelerators()) { + + CloseButton.KeyboardAccelerators().Append(keyboardAccelerator); + } + + //Microsoft::UI::Xaml::Controls::Image Image = GetTemplateChild(L"ContentImage").try_as(); + + //Image.ImageOpened([this](IInspectable const& sender, Microsoft::UI::Xaml::RoutedEventArgs const& args) + //{ + // auto image = sender.as(); + + // if (image) + // { + // // 获取图片源并转换为BitmapImage + // auto bitmapImage = image.Source().as(); + // if (bitmapImage) + // { + // // 获取图片实际宽高(像素) + // double width = bitmapImage.PixelWidth(); + // double height = bitmapImage.PixelHeight(); + + // // 输出尺寸信息 + // //std::wcout << L"图片尺寸: " << width << L" x " << height << std::endl; + + // // 设置父容器Grid的尺寸为图片尺寸 + // if (auto parentGrid = image.Parent().as()) + // { + // parentGrid.Width(width); + // parentGrid.Height(height); + // } + // } + // } + //}); + + + //isCustomMeasureFinishedAfterLoaded = true; + //winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"DialogShowingWithoutSmokeLayer", false); + //DetermineButtonsVisibilityState(); + //DetermineDefaultButtonStates(); + //DetermineWidthLimit(); + + //buttonsVisibilityState = DetermineButtonsVisibilityState(); + //defaultButtonState = DetermineDefaultButtonState(); + //isCustomMeasureFinishedAfterLoaded = IsLoaded(); + } + + Windows::Foundation::Size ContentDialogContent::MeasureOverride(Windows::Foundation::Size availableSize) + { + + if (isCustomMeasureFinishedAfterLoaded || (IsLoaded())) + return base_type::MeasureOverride(CustomMeasure(availableSize)); + + isCustomMeasureFinishedAfterLoaded = IsLoaded(); + return CustomMeasure(availableSize); + + } + + Windows::Foundation::Size ContentDialogContent::CustomMeasure(Windows::Foundation::Size availableSize) + { + int countButtons = 0; + double buttonLongestWidth = 0.0; + double buttonMaxWidth = unbox_value(Microsoft::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"ContentDialogButtonMaxWidth"))); + + if (PrimaryButton.Visibility() == Microsoft::UI::Xaml::Visibility::Visible) + { + PrimaryButton.Measure(availableSize); + buttonLongestWidth = std::min(std::max(buttonLongestWidth, PrimaryButton.DesiredSize().Width), buttonMaxWidth); + countButtons++; + } + + if (SecondaryButton.Visibility() == Microsoft::UI::Xaml::Visibility::Visible) + { + SecondaryButton.Measure(availableSize); + buttonLongestWidth = std::min(std::max(buttonLongestWidth, SecondaryButton.DesiredSize().Width), buttonMaxWidth); + countButtons++; + } + + if (CloseButton.Visibility() == Microsoft::UI::Xaml::Visibility::Visible) + { + CloseButton.Measure(availableSize); + buttonLongestWidth = std::min(std::max(buttonLongestWidth, CloseButton.DesiredSize().Width), buttonMaxWidth); + countButtons++; + } + + // 假设 CommandSpace 是一个具有 Padding 属性的元素 + Microsoft::UI::Xaml::Thickness commandSpacePadding = CommandSpace().Padding(); + double commandSpaceExpectedWidth = commandSpacePadding.Left + commandSpacePadding.Right + + countButtons * buttonLongestWidth + + (countButtons - 1) * winrt::unbox_value(Microsoft::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"ContentDialogButtonSpacing"))).Value; + + double minWidth = std::max( + unbox_value(Microsoft::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"ContentDialogMinWidth"))), + commandSpaceExpectedWidth + ); + + double maxWidth = std::max( + unbox_value(Microsoft::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"ContentDialogMaxWidth"))), + commandSpaceExpectedWidth + ); + + if (availableSize.Width > (float)maxWidth) + { + availableSize.Width = (float)maxWidth; + } + + Windows::Foundation::Size desiredSize = base_type::MeasureOverride(availableSize); + + if (desiredSize.Width < minWidth) + { + desiredSize.Width = (float)minWidth; + } + + return desiredSize; + } + + winrt::hstring ContentDialogContent::DetermineButtonsVisibilityState() { + + if (!PrimaryButtonText().empty() && !SecondaryButtonText().empty() && !CloseButtonText().empty()) + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"AllVisible", false); + + //IsPrimaryButtonEnabled(true); + //IsSecondaryButtonEnabled(true); + + return L"AllVisible"; + } + else if (!PrimaryButtonText().empty()) + { + + //IsPrimaryButtonEnabled(true); + + if (!SecondaryButtonText().empty()) + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"PrimaryAndSecondaryVisible", false); + IsSecondaryButtonEnabled(true); + return L"PrimaryAndSecondaryVisible"; + } + else if (!CloseButtonText().empty()) + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"PrimaryAndCloseVisible", false); + IsSecondaryButtonEnabled(false); + return L"PrimaryAndCloseVisible"; + } + else + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"PrimaryVisible", false); + IsSecondaryButtonEnabled(false); + return L"PrimaryVisible"; + } + + } + else if (!SecondaryButtonText().empty()) + { + //IsSecondaryButtonEnabled(true); + + if (!CloseButtonText().empty()) + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"SecondaryAndCloseVisible", false); + return L"SecondaryAndCloseVisible"; + } + else + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"SecondaryVisible", false); + return L"SecondaryAndCloseVisible"; + } + + } + else if (!CloseButtonText().empty()) + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"CloseVisible", false); + return L"CloseVisible"; + } + else + { + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"NoneVisible", false); + IsPrimaryButtonEnabled(false); + IsSecondaryButtonEnabled(false); + return L"NoneVisible"; + } + } + + winrt::hstring ContentDialogContent::DetermineDefaultButtonState() { + + switch (DefaultButton()) + { + case Microsoft::UI::Xaml::Controls::ContentDialogButton::Primary: { + + Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"PrimaryAsDefaultButton", false); + winrt::Microsoft::UI::Xaml::Input::KeyboardAccelerator keyboardAccelerator = {}; + keyboardAccelerator.Key(winrt::Windows::System::VirtualKey::Enter); + PrimaryButton.KeyboardAccelerators().Append(keyboardAccelerator); + + PrimaryButton.Focus(Microsoft::UI::Xaml::FocusState::Programmatic); + return L"PrimaryAsDefaultButton"; + + } + + case Microsoft::UI::Xaml::Controls::ContentDialogButton::Secondary: { + + Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"SecondaryAsDefaultButton", false); + + winrt::Microsoft::UI::Xaml::Input::KeyboardAccelerator keyboardAccelerator = {}; + keyboardAccelerator.Key(winrt::Windows::System::VirtualKey::Enter); + SecondaryButton.KeyboardAccelerators().Append(keyboardAccelerator); + + SecondaryButton.Focus(Microsoft::UI::Xaml::FocusState::Programmatic); + return L"SecondaryAsDefaultButton"; + + } + case Microsoft::UI::Xaml::Controls::ContentDialogButton::Close: { + + Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"CloseAsDefaultButton", false); + + winrt::Microsoft::UI::Xaml::Input::KeyboardAccelerator keyboardAccelerator = {}; + keyboardAccelerator.Key(winrt::Windows::System::VirtualKey::Enter); + CloseButton.KeyboardAccelerators().Append(keyboardAccelerator); + CloseButton.Focus(Microsoft::UI::Xaml::FocusState::Programmatic); + return L"CloseAsDefaultButton"; + + } + case Microsoft::UI::Xaml::Controls::ContentDialogButton::None: { + Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"NoDefaultButton", false); + return L"NoDefaultButton"; + } + + default: { + Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"NoDefaultButton", false); + return L"NoDefaultButton"; + } + + } + } + + void ContentDialogContent::AfterGotFocus() + { + if (IsHeaderImage()) return; + + winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, defaultButtonState, false); + } + + void ContentDialogContent::AfterLostFocus() + { + + if (IsHeaderImage()) return; + + Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, L"NoDefaultButton", false); + } + + void ContentDialogContent::TitleArea(Microsoft::UI::Xaml::UIElement const& Element) + { + m_TitleArea = Element; + } + winrt::Microsoft::UI::Xaml::UIElement ContentDialogContent::TitleArea() + { + return m_TitleArea; + } + + void ContentDialogContent::DialogSpace(Microsoft::UI::Xaml::Controls::Grid const& grid) + { + m_DialogSpace = grid; + } + winrt::Microsoft::UI::Xaml::Controls::Grid ContentDialogContent::DialogSpace() + { + return m_DialogSpace; + } + + void ContentDialogContent::CommandSpace(Microsoft::UI::Xaml::Controls::Grid const& grid) + { + m_CommandSpace = grid; + } + winrt::Microsoft::UI::Xaml::Controls::Grid ContentDialogContent::CommandSpace() + { + return m_CommandSpace; + } + + winrt::event_token ContentDialogContent::PrimaryButtonClick(winrt::Windows::Foundation::EventHandler const& handler) + { + return m_PrimaryButtonClick.add(handler); + } + void ContentDialogContent::PrimaryButtonClick(winrt::event_token const& token) + { + m_PrimaryButtonClick.remove(token); + } + + winrt::event_token ContentDialogContent::SecondaryButtonClick(winrt::Windows::Foundation::EventHandler const& handler) + { + return m_SecondaryButtonClick.add(handler); + } + void ContentDialogContent::SecondaryButtonClick(winrt::event_token const& token) + { + m_SecondaryButtonClick.remove(token); + } + + winrt::event_token ContentDialogContent::CloseButtonClick(winrt::Windows::Foundation::EventHandler const& handler) + { + return m_CloseButtonClick.add(handler); + } + void ContentDialogContent::CloseButtonClick(winrt::event_token const& token) + { + m_CloseButtonClick.remove(token); + } + + + winrt::event_token ContentDialogContent::ContentRightTapped(Windows::Foundation::TypedEventHandler const& handler) + { + return m_ContentRightTapped.add(handler); + } + + void ContentDialogContent::ContentRightTapped(winrt::event_token const& token) + { + m_ContentRightTapped.remove(token); + } + + + winrt::Windows::Foundation::Collections::IVector ContentDialogContent::PrimaryButtonKeyboardAccelerators() + { + return m_PrimaryButtonKeyboardAccelerators; + } + + + winrt::Windows::Foundation::Collections::IVector ContentDialogContent::SecondaryButtonKeyboardAccelerators() + { + return m_SecondaryButtonKeyboardAccelerators; + } + + + winrt::Windows::Foundation::Collections::IVector ContentDialogContent::CloseButtonKeyboardAccelerators() + { + return m_CloseButtonKeyboardAccelerators; + } + +} diff --git a/WinUI3Package/ContentDialogContent.h b/WinUI3Package/ContentDialogContent.h new file mode 100644 index 0000000..29d14fa --- /dev/null +++ b/WinUI3Package/ContentDialogContent.h @@ -0,0 +1,169 @@ +#pragma once + +#include "ContentDialogContent.g.h" + +#include "include/cppwinrt_utils.h" + +namespace winrt::WinUI3Package::implementation +{ + struct ContentDialogContent : ContentDialogContentT + { + using Super = ContentDialogContentT; + + + ContentDialogContent(); + ~ContentDialogContent(); + + void OnApplyTemplate(); + + Windows::Foundation::Size MeasureOverride(Windows::Foundation::Size availableSize); + + Windows::Foundation::Size CustomMeasure(Windows::Foundation::Size availableSize); + + void AfterGotFocus(); + + void AfterLostFocus(); + + //void DetermineButtonsVisibilityState(); + //void DetermineDefaultButtonStates(); + winrt::hstring DetermineButtonsVisibilityState(); + winrt::hstring DetermineDefaultButtonState(); + + void DetermineWidthLimit(); + void RemoveSizeLimit(); + + void TitleArea(Microsoft::UI::Xaml::UIElement const& Element); + Microsoft::UI::Xaml::UIElement TitleArea(); + + void DialogSpace(Microsoft::UI::Xaml::Controls::Grid const& grid); + Microsoft::UI::Xaml::Controls::Grid DialogSpace(); + + void CommandSpace(Microsoft::UI::Xaml::Controls::Grid const& grid); + Microsoft::UI::Xaml::Controls::Grid CommandSpace(); + + winrt::event_token PrimaryButtonClick(winrt::Windows::Foundation::EventHandler const& handler); + void PrimaryButtonClick(winrt::event_token const& token); + + winrt::event_token SecondaryButtonClick(winrt::Windows::Foundation::EventHandler const& handler); + void SecondaryButtonClick(winrt::event_token const& token); + + winrt::event_token CloseButtonClick(winrt::Windows::Foundation::EventHandler const& handler); + void CloseButtonClick(winrt::event_token const& token); + + winrt::event_token ContentRightTapped(Windows::Foundation::TypedEventHandler const& handler); + void ContentRightTapped(winrt::event_token const& token); + + static void OnButtonTextChangedStatic(Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs e) + { + UNREFERENCED_PARAMETER(sender); + UNREFERENCED_PARAMETER(e); + + //winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, IsEnabled() ? NormalState : DisabledState, true); + + auto self = get_self(sender.as()); + + if (self->IsLoaded()) + { + self->buttonsVisibilityState = self->DetermineButtonsVisibilityState(); + self->isCustomMeasureFinishedAfterLoaded = false; + } + + } + + static void OnDefaultButtonChangedStatic(Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs e) + { + UNREFERENCED_PARAMETER(sender); + UNREFERENCED_PARAMETER(e); + + //winrt::Microsoft::UI::Xaml::VisualStateManager::GoToState(*this, IsEnabled() ? NormalState : DisabledState, true); + + auto self = get_self(sender.as()); + + if (self->IsLoaded()) + { + self->defaultButtonState = self->DetermineDefaultButtonState(); + } + + } + + + static winrt::Windows::UI::Xaml::Style DefaultButtonStyle() + { + static auto style = Microsoft::UI::Xaml::Application::Current().Resources().TryLookup( + winrt::box_value(L"DefaultButtonStyle") + ).as(); + + return style; + } + //static void OnIsClickEnabledPropertyChangedStatic(Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs args) + //{ + // UNREFERENCED_PARAMETER(sender); + // UNREFERENCED_PARAMETER(args); + // get_self(sender.as())->OnIsClickEnabledPropertyChanged(args.OldValue().as(), args.NewValue().as()); + + //} + + winrt::Windows::Foundation::Collections::IVector PrimaryButtonKeyboardAccelerators(); + winrt::Windows::Foundation::Collections::IVector SecondaryButtonKeyboardAccelerators(); + winrt::Windows::Foundation::Collections::IVector CloseButtonKeyboardAccelerators(); + + + DEFINE_PROPERTY(bool, IsHeaderImage); + + DEPENDENCY_PROPERTY(winrt::Windows::Foundation::IInspectable, Title); + DEPENDENCY_PROPERTY(Microsoft::UI::Xaml::DataTemplate, TitleTemplate); + DEPENDENCY_PROPERTY(winrt::hstring, PrimaryButtonText); + DEPENDENCY_PROPERTY(winrt::hstring, SecondaryButtonText); + DEPENDENCY_PROPERTY(winrt::hstring, CloseButtonText); + + DEPENDENCY_PROPERTY(bool, IsPrimaryButtonEnabled); + DEPENDENCY_PROPERTY(bool, IsSecondaryButtonEnabled); + + DEPENDENCY_PROPERTY(Microsoft::UI::Xaml::Controls::ContentDialogButton, DefaultButton); + + DEPENDENCY_PROPERTY(Microsoft::UI::Xaml::Style, PrimaryButtonStyle); + DEPENDENCY_PROPERTY(Microsoft::UI::Xaml::Style, SecondaryButtonStyle); + DEPENDENCY_PROPERTY(Microsoft::UI::Xaml::Style, CloseButtonStyle); + + private: + + bool isCustomMeasureFinishedAfterLoaded; + + Microsoft::UI::Xaml::Controls::Button PrimaryButton{ nullptr }; + Microsoft::UI::Xaml::Controls::Button SecondaryButton{ nullptr }; + Microsoft::UI::Xaml::Controls::Button CloseButton{ nullptr }; + + winrt::event> m_PrimaryButtonClick; + winrt::event> m_SecondaryButtonClick; + winrt::event> m_CloseButtonClick; + + winrt::event> m_ContentRightTapped; + + + Microsoft::UI::Xaml::UIElement m_TitleArea{ nullptr }; + Microsoft::UI::Xaml::Controls::Grid m_DialogSpace{ nullptr }; + Microsoft::UI::Xaml::Controls::Grid m_CommandSpace{ nullptr }; + + winrt::hstring buttonsVisibilityState; + winrt::hstring defaultButtonState; + + winrt::event_token m_OnUnloaded; + + winrt::event_token m_OnPrimaryButtonClick; + winrt::event_token m_OnSecondaryButtonClick; + winrt::event_token m_OnCloseButtonClick; + + + winrt::Windows::Foundation::Collections::IVector m_PrimaryButtonKeyboardAccelerators{ nullptr }; + winrt::Windows::Foundation::Collections::IVector m_SecondaryButtonKeyboardAccelerators{ nullptr }; + winrt::Windows::Foundation::Collections::IVector m_CloseButtonKeyboardAccelerators{ nullptr }; + + }; +} + +namespace winrt::WinUI3Package::factory_implementation +{ + struct ContentDialogContent : ContentDialogContentT + { + }; +} diff --git a/WinUI3Package/ContentDialogContent.idl b/WinUI3Package/ContentDialogContent.idl new file mode 100644 index 0000000..4efbbc0 --- /dev/null +++ b/WinUI3Package/ContentDialogContent.idl @@ -0,0 +1,60 @@ +import "ContentDialogWindowButtonClickEventArgs.idl"; + + +namespace WinUI3Package +{ + [bindable] + [default_interface] + runtimeclass ContentDialogContent : Microsoft.UI.Xaml.Controls.ContentControl + { + ContentDialogContent(); + + void AfterGotFocus(); + void AfterLostFocus(); + + Microsoft.UI.Xaml.UIElement TitleArea{ get; set; }; + Microsoft.UI.Xaml.Controls.Grid DialogSpace{ get; set; }; + Microsoft.UI.Xaml.Controls.Grid CommandSpace{ get; set; }; + + Object Title; + Microsoft.UI.Xaml.DataTemplate TitleTemplate; + + + Boolean IsHeaderImage; + + String PrimaryButtonText; + String SecondaryButtonText; + String CloseButtonText; + + Boolean IsPrimaryButtonEnabled; + Boolean IsSecondaryButtonEnabled; + + Microsoft.UI.Xaml.Controls.ContentDialogButton DefaultButton; + + Microsoft.UI.Xaml.Style PrimaryButtonStyle; + Microsoft.UI.Xaml.Style SecondaryButtonStyle; + Microsoft.UI.Xaml.Style CloseButtonStyle; + + Windows.Foundation.Collections.IVector PrimaryButtonKeyboardAccelerators{ get; }; + Windows.Foundation.Collections.IVector SecondaryButtonKeyboardAccelerators{ get; }; + Windows.Foundation.Collections.IVector CloseButtonKeyboardAccelerators{ get; }; + + + static Microsoft.UI.Xaml.DependencyProperty TitleProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty PrimaryButtonTextProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty SecondaryButtonTextProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty CloseButtonTextProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty IsPrimaryButtonEnabledProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty DefaultButtonProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty PrimaryButtonStyleProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty SecondaryButtonStyleProperty{ get; }; + static Microsoft.UI.Xaml.DependencyProperty CloseButtonStyleProperty{ get; }; + + + event Windows.Foundation.TypedEventHandler ContentRightTapped; + + event Windows.Foundation.EventHandler PrimaryButtonClick; + event Windows.Foundation.EventHandler SecondaryButtonClick; + event Windows.Foundation.EventHandler CloseButtonClick; + } +} diff --git a/WinUI3Package/ContentDialogContent_Resource.xaml b/WinUI3Package/ContentDialogContent_Resource.xaml new file mode 100644 index 0000000..89b8a7e --- /dev/null +++ b/WinUI3Package/ContentDialogContent_Resource.xaml @@ -0,0 +1,282 @@ + + + + + #4C3A3A3A + + + + + + + #80FFFFFF + + + + + + + + + + + + + + 24,24,24,0 + 24,0,24,24 + #0F000000 + #19000000 + + + + + + +