fix: 优化 XAML 绑定

This commit is contained in:
刘旭 2022-06-02 15:22:29 +08:00
commit f59c19a2ec
12 changed files with 99 additions and 30 deletions

View file

@ -9,6 +9,7 @@
using namespace winrt;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
@ -25,7 +26,7 @@ const DependencyProperty PageFrame::MainContentProperty = DependencyProperty::Re
L"MainContent",
xaml_typename<IInspectable>(),
xaml_typename<Magpie::PageFrame>(),
PropertyMetadata(nullptr)
PropertyMetadata(nullptr, &PageFrame::_OnTitleChanged)
);
@ -61,12 +62,27 @@ void PageFrame::ScrollViewer_ViewChanging(IInspectable const&, ScrollViewerViewC
Utils::CloseAllXamlPopups(XamlRoot());
}
event_token PageFrame::PropertyChanged(PropertyChangedEventHandler const& value) {
return _propertyChangedEvent.add(value);
}
void PageFrame::PropertyChanged(event_token const& token) {
_propertyChangedEvent.remove(token);
}
void PageFrame::_Update() {
TitleTextBlock().Visibility(Title().empty() ? Visibility::Collapsed : Visibility::Visible);
}
void PageFrame::_OnTitleChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
get_self<PageFrame>(sender.as<default_interface<PageFrame>>())->_Update();
PageFrame* that = get_self<PageFrame>(sender.as<default_interface<PageFrame>>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Title" });
}
void PageFrame::_OnMainContentChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
PageFrame* that = get_self<PageFrame>(sender.as<default_interface<PageFrame>>());
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"MainContent" });
}
}

View file

@ -25,13 +25,19 @@ struct PageFrame : PageFrameT<PageFrame> {
void ScrollViewer_PointerPressed(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::Input::PointerRoutedEventArgs const&);
void ScrollViewer_ViewChanging(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::Controls::ScrollViewerViewChangingEventArgs const&);
event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value);
void PropertyChanged(event_token const& token);
static const Windows::UI::Xaml::DependencyProperty TitleProperty;
static const Windows::UI::Xaml::DependencyProperty MainContentProperty;
private:
static void _OnTitleChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
static void _OnMainContentChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
void _Update();
event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> _propertyChangedEvent;
};
}

View file

@ -1,8 +1,7 @@
namespace Magpie
{
[default_interface]
[Windows.UI.Xaml.Markup.ContentProperty("MainContent")]
runtimeclass PageFrame : Windows.UI.Xaml.Controls.UserControl
runtimeclass PageFrame : Windows.UI.Xaml.Controls.UserControl, [default] Windows.UI.Xaml.Data.INotifyPropertyChanged
{
PageFrame();

View file

@ -15,28 +15,28 @@ DependencyProperty SettingItem::TitleProperty = DependencyProperty::Register(
L"Title",
xaml_typename<hstring>(),
xaml_typename<Magpie::SettingItem>(),
PropertyMetadata(box_value(L""), nullptr)
PropertyMetadata(box_value(L""), _OnTitleChanged)
);
DependencyProperty SettingItem::DescriptionProperty = DependencyProperty::Register(
L"Description",
xaml_typename<IInspectable>(),
xaml_typename<Magpie::SettingItem>(),
PropertyMetadata(nullptr, &SettingItem::_OnPropertyChanged)
PropertyMetadata(nullptr, &SettingItem::_OnDescriptionChanged)
);
DependencyProperty SettingItem::IconProperty = DependencyProperty::Register(
L"Icon",
xaml_typename<IInspectable>(),
xaml_typename<Magpie::SettingItem>(),
PropertyMetadata(nullptr, &SettingItem::_OnPropertyChanged)
PropertyMetadata(nullptr, &SettingItem::_OnIconChanged)
);
DependencyProperty SettingItem::ActionContentProperty = DependencyProperty::Register(
L"ActionContent",
xaml_typename<IInspectable>(),
xaml_typename<Magpie::SettingItem>(),
nullptr
PropertyMetadata(nullptr, &SettingItem::_OnActionContentChanged)
);
SettingItem::SettingItem() {
@ -75,8 +75,28 @@ IInspectable SettingItem::ActionContent() const {
return GetValue(ActionContentProperty);
}
void SettingItem::_OnPropertyChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
get_self<SettingItem>(sender.as<default_interface<SettingItem>>())->_Update();
void SettingItem::_OnTitleChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
SettingItem* that = get_self<SettingItem>(sender.as<default_interface<SettingItem>>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Title" });
}
void SettingItem::_OnDescriptionChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
SettingItem* that = get_self<SettingItem>(sender.as<default_interface<SettingItem>>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Description" });
}
void SettingItem::_OnIconChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
SettingItem* that = get_self<SettingItem>(sender.as<default_interface<SettingItem>>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Icon" });
}
void SettingItem::_OnActionContentChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
SettingItem* that = get_self<SettingItem>(sender.as<default_interface<SettingItem>>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"ActionContent" });
}
void SettingItem::_Update() {
@ -97,4 +117,12 @@ void SettingItem::Loading(Windows::UI::Xaml::FrameworkElement const&, Windows::F
_Update();
}
event_token SettingItem::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value) {
return _propertyChangedEvent.add(value);
}
void SettingItem::PropertyChanged(event_token const& token) {
_propertyChangedEvent.remove(token);
}
}

View file

@ -31,17 +31,25 @@ struct SettingItem : SettingItemT<SettingItem> {
void IsEnabledChanged(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
void Loading(Windows::UI::Xaml::FrameworkElement const&, Windows::Foundation::IInspectable const&);
event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value);
void PropertyChanged(event_token const& token);
static Windows::UI::Xaml::DependencyProperty TitleProperty;
static Windows::UI::Xaml::DependencyProperty DescriptionProperty;
static Windows::UI::Xaml::DependencyProperty IconProperty;
static Windows::UI::Xaml::DependencyProperty ActionContentProperty;
private:
static void _OnPropertyChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
static void _OnTitleChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
static void _OnDescriptionChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
static void _OnIconChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
static void _OnActionContentChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
void _Update();
void _SetEnabledState();
event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> _propertyChangedEvent;
};
}

View file

@ -1,9 +1,8 @@
namespace Magpie
{
[default_interface]
[Windows.UI.Xaml.TemplateVisualState("Normal", "CommonStates")]
[Windows.UI.Xaml.TemplateVisualState("Disabled", "CommonStates")]
runtimeclass SettingItem : Windows.UI.Xaml.Controls.UserControl
runtimeclass SettingItem : Windows.UI.Xaml.Controls.UserControl, [default] Windows.UI.Xaml.Data.INotifyPropertyChanged
{
SettingItem();

View file

@ -22,20 +22,20 @@ const DependencyProperty SettingsGroup::TitleProperty = DependencyProperty::Regi
L"Title",
xaml_typename<hstring>(),
xaml_typename<Magpie::SettingsGroup>(),
PropertyMetadata(box_value(L""), &SettingsGroup::_OnPropertyChanged)
PropertyMetadata(box_value(L""), &SettingsGroup::_OnTitleChanged)
);
const DependencyProperty SettingsGroup::DescriptionProperty = DependencyProperty::Register(
L"Description",
xaml_typename<IInspectable>(),
xaml_typename<Magpie::SettingsGroup>(),
PropertyMetadata(nullptr, &SettingsGroup::_OnPropertyChanged)
PropertyMetadata(nullptr, &SettingsGroup::_OnDescriptionChanged)
);
SettingsGroup::SettingsGroup() {
InitializeComponent();
Children(PART_Host().Children());
Children(ChildrenHost().Children());
}
void SettingsGroup::Title(const hstring& value) {
@ -71,8 +71,24 @@ void SettingsGroup::Loading(FrameworkElement const&, IInspectable const&) {
_Update();
}
void SettingsGroup::_OnPropertyChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
get_self<SettingsGroup>(sender.as<default_interface<SettingsGroup>>())->_Update();
event_token SettingsGroup::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value) {
return _propertyChangedEvent.add(value);
}
void SettingsGroup::PropertyChanged(event_token const& token) {
_propertyChangedEvent.remove(token);
}
void SettingsGroup::_OnTitleChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
SettingsGroup* that = get_self<SettingsGroup>(sender.as<default_interface<SettingsGroup>>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Title" });
}
void SettingsGroup::_OnDescriptionChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
SettingsGroup* that = get_self<SettingsGroup>(sender.as<default_interface<SettingsGroup>>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Description" });
}
void SettingsGroup::_Update() {

View file

@ -24,19 +24,24 @@ struct SettingsGroup : SettingsGroupT<SettingsGroup> {
void Children(Windows::UI::Xaml::Controls::UIElementCollection const& value);
void IsEnabledChanged(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
void Loading(Windows::UI::Xaml::FrameworkElement const&, Windows::Foundation::IInspectable const&);
event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value);
void PropertyChanged(event_token const& token);
static const Windows::UI::Xaml::DependencyProperty ChildrenProperty;
static const Windows::UI::Xaml::DependencyProperty TitleProperty;
static const Windows::UI::Xaml::DependencyProperty DescriptionProperty;
private:
static void _OnPropertyChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
static void _OnTitleChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
static void _OnDescriptionChanged(Windows::UI::Xaml::DependencyObject const& sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);
void _Update();
void _SetEnabledState();
event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> _propertyChangedEvent;
};
}

View file

@ -1,10 +1,9 @@
namespace Magpie
{
[default_interface]
[Windows.UI.Xaml.Markup.ContentProperty("Children")]
[Windows.UI.Xaml.TemplateVisualState("Normal", "CommonStates")]
[Windows.UI.Xaml.TemplateVisualState("Disabled", "CommonStates")]
runtimeclass SettingsGroup : Windows.UI.Xaml.Controls.UserControl
runtimeclass SettingsGroup : Windows.UI.Xaml.Controls.UserControl, [default] Windows.UI.Xaml.Data.INotifyPropertyChanged
{
SettingsGroup();

View file

@ -34,7 +34,7 @@
</ContentPresenter.Resources>
</ContentPresenter>
<StackPanel Orientation="Vertical" Spacing="2" Margin="0,6,0,0" x:Name="PART_Host">
<StackPanel Orientation="Vertical" Spacing="2" Margin="0,6,0,0" x:Name="ChildrenHost">
</StackPanel>
<VisualStateManager.VisualStateGroups>

View file

@ -36,9 +36,4 @@ void SettingsPage::ComboBox_DropDownOpened(IInspectable const&, IInspectable con
Utils::UpdateThemeOfXamlPopups(XamlRoot(), ActualTheme());
}
void SettingsPage::ScrollViewer_PointerPressed(IInspectable const&, PointerRoutedEventArgs const&) {
// ThemeComboBox().IsDropDownOpen(false);
Utils::CloseAllXamlPopups(XamlRoot());
}
}

View file

@ -14,8 +14,6 @@ struct SettingsPage : SettingsPageT<SettingsPage> {
void ComboBox_DropDownOpened(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::Foundation::IInspectable const&);
void ScrollViewer_PointerPressed(winrt::Windows::Foundation::IInspectable const&, Windows::UI::Xaml::Input::PointerRoutedEventArgs const&);
private:
Magpie::Settings _settings{ nullptr };
};