Is it possible to add a static event to an attached property and lazy-initialize it? #4360
-
I'd like to instantly change the language for an unpackaged application. As I known that the PrimaryLanguageOverride was not able for unpackaged applications, I thought it might be possible utilizing attached properties and events inspired by WinUI3Localizer. But it was written by C#, and I was developing with C++/WinRT, so there were a lot problems I need to resolve. Follow the UWP guide I wrote a customed attached property to implement a custom struct UidTrans : UidTransT<UidTrans>, winrt::Microsoft::UI::Xaml::DependencyObject {
private:
static winrt::Microsoft::UI::Xaml::DependencyProperty uidProperty;
static winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::UI::Xaml::DependencyObject>> uidTransSetEvent;
public:
static void Initialize();
static winrt::Microsoft::UI::Xaml::DependencyProperty UidProperty() { return uidProperty; }
static winrt::hstring GetUid(const winrt::Microsoft::UI::Xaml::DependencyObject& target);
static void SetUid(const winrt::Microsoft::UI::Xaml::DependencyObject& target, const winrt::hstring& uid);
static winrt::event_token UidTransSet(winrt::Windows::Foundation::EventHandler<winrt::Microsoft::UI::Xaml::DependencyObject> const& handler);
static void UidTransSet(winrt::event_token const& token) noexcept;
}; In the // Assign static member properties to null to avoid static initialization order fiasco.
winrt::Microsoft::UI::Xaml::DependencyProperty UidTrans::uidProperty = nullptr;
// ERROR: winrt::event cannot be assigned with nullptr
winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::UI::Xaml::DependencyObject>> uidTransSetEvent = nullptr;
// Static initialization function.
void UidTrans::Initialize() {
uidProperty = winrt::Microsoft::UI::Xaml::DependencyProperty::RegisterAttached(L"Uid", winrt::xaml_typename<winrt::hstring>(), winrt::xaml_typename<DynamicScanDiagnosis::UidTrans>(), winrt::Microsoft::UI::Xaml::PropertyMetadata{ winrt::box_value(L"") });
// ERROR: The operator "=" of winrt::event has been deleted.
uidTransSetEvent = winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::UI::Xaml::DependencyObject>>();
}
winrt::hstring UidTrans::GetUid(const winrt::Microsoft::UI::Xaml::DependencyObject& target) {
return winrt::unbox_value<winrt::hstring>(target.GetValue(uidProperty));
}
void UidTrans::SetUid(const winrt::Microsoft::UI::Xaml::DependencyObject& target, const winrt::hstring& uid) {
target.SetValue(uidProperty, winrt::box_value(uid));
uidTransSetEvent.add(target);
}
winrt::event_token UidTrans::UidTransSet(winrt::Windows::Foundation::EventHandler<winrt::Microsoft::UI::Xaml::DependencyObject> const& handler) {
return uidTransSetEvent.add(handler);
}
void UidTrans::UidTransSet(winrt::event_token const& token) noexcept {
uidTransSetEvent.remove(token);
} To make the static properties lazy-initialized, the initialized function is called in App::App() {
UidTrans::Initialize();
InitializeComponent();
} So the problem seems that how to lazy-initialize the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Event is a structure, but it isn't a smart pointer class like winrt::Microsoft::UI::Xaml::DependencyProperty or winrt::Microsoft::UI::Xaml::DependencyObject. So the only way to have lazy initialisation on event is to use std::optional or a pointer (std::unique_pointer would be preferred for lifetime reasons.) |
Beta Was this translation helpful? Give feedback.
Event is a structure, but it isn't a smart pointer class like winrt::Microsoft::UI::Xaml::DependencyProperty or winrt::Microsoft::UI::Xaml::DependencyObject. So the only way to have lazy initialisation on event is to use std::optional or a pointer (std::unique_pointer would be preferred for lifetime reasons.)
It isn't, however, much of a problem to just initialise it as is, since it doesn't contain anything too big on construction.