CppXAML
Loading...
Searching...
No Matches
VisualState.h
Go to the documentation of this file.
1#pragma once
2#include <winrt/Windows.Foundation.h>
3#include <cppxaml/utils.h>
4
13namespace cppxaml {
14 namespace details {
15
16 cppxaml::xaml::FrameworkElement FindChildWithVSG(cppxaml::xaml::FrameworkElement fe) {
17 cppxaml::xaml::FrameworkElement root{ nullptr };
18 for (auto i = 0; i < cppxaml::xaml::Media::VisualTreeHelper::GetChildrenCount(fe); i++) {
19 auto child = cppxaml::xaml::Media::VisualTreeHelper::GetChild(fe, i);
20 if (auto childFE = child.try_as<cppxaml::xaml::FrameworkElement>()) {
21 winrt::Windows::Foundation::Collections::IVector<cppxaml::xaml::VisualStateGroup> vsgs = cppxaml::xaml::VisualStateManager::GetVisualStateGroups(childFE);
22 if (vsgs.Size() != 0) {
23 root = childFE;
24 break;
25 }
26 }
27 }
28 return root;
29 }
30
31 // TODO: make the callback take a template parameter so we don't have to cast from IInspectable
32 struct VSMListener : winrt::implements<VSMListener, winrt::Windows::Foundation::IInspectable> {
33
34 VSMListener(cppxaml::xaml::FrameworkElement fe, const std::unordered_map<std::wstring, cppxaml::xaml::VisualStateChangedEventHandler>& map) : m_map(map) {
35 if (auto root = FindChildWithVSG(fe)) {
36 for (const cppxaml::xaml::VisualStateGroup& vsg : cppxaml::xaml::VisualStateManager::GetVisualStateGroups(root)) {
37 vsg.CurrentStateChanged([_this = this->get_strong(), fe](winrt::Windows::Foundation::IInspectable sender, cppxaml::xaml::VisualStateChangedEventArgs args) {
38
39 auto newState = args.NewState();
40 auto newName = newState.Name();
41 const auto newNameStr = newName.c_str();
42 if (_this->m_map.find(newNameStr) != _this->m_map.end()) {
43 _this->m_map[newNameStr](fe, args);
44 }
45 });
46 }
47 }
48
49 }
50
51 private:
52 std::unordered_map<std::wstring, cppxaml::xaml::VisualStateChangedEventHandler> m_map{};
53 };
54 }
55
56 template<typename TFrameworkElement>
57 auto VSMListener(TFrameworkElement obj, const std::unordered_map<std::wstring, cppxaml::xaml::VisualStateChangedEventHandler>& map) {
58 cppxaml::xaml::FrameworkElement fe(obj);
59 if (!fe.Parent()) {
60 fe.Loaded([map](winrt::Windows::Foundation::IInspectable sender, auto&) {
61 auto listener = winrt::make_self<cppxaml::details::VSMListener>(sender.as<cppxaml::xaml::FrameworkElement>(), map);
62 });
63 }
64 else {
65 auto listener = winrt::make_self<cppxaml::details::VSMListener>(fe, map);
66 }
67 return obj;
68 }
69
70}
The main CppXAML namespace.