From 3ca919e761be9a025b9412d97a7e024f8997c28e Mon Sep 17 00:00:00 2001 From: Stephen L Peters Date: Mon, 25 Nov 2019 22:52:59 -0800 Subject: [PATCH] RadioButtons API feedback (#1675) --- ...rUniformToLargestGridLayout.properties.cpp | 48 +++--- ...jorUniformToLargestGridLayout.properties.h | 18 +-- dev/Generated/RadioButtons.properties.cpp | 55 +++++-- dev/Generated/RadioButtons.properties.h | 19 ++- .../ColumnMajorUniformToLargestGridLayout.cpp | 15 +- .../ColumnMajorUniformToLargestGridLayout.h | 2 +- .../RadioButtonsTestPageElements.cs | 38 ++++- .../InteractionTests/RadioButtonsTests.cs | 140 ++++++++++++++++-- dev/RadioButtons/RadioButtons.cpp | 62 ++++++-- dev/RadioButtons/RadioButtons.h | 2 + dev/RadioButtons/RadioButtons.idl | 13 +- dev/RadioButtons/RadioButtons.xaml | 6 +- .../RadioButtonsElementFactory.cpp | 4 - dev/RadioButtons/RadioButtonsElementFactory.h | 4 +- dev/RadioButtons/RadioButtonsPrimitives.idl | 17 +-- dev/RadioButtons/TestUI/RadioButtonsPage.xaml | 53 ++++--- .../TestUI/RadioButtonsPage.xaml.cs | 60 +++++++- dev/inc/SharedHelpers.h | 9 ++ 18 files changed, 424 insertions(+), 141 deletions(-) diff --git a/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.cpp b/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.cpp index 4930497024..49eacea17a 100644 --- a/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.cpp +++ b/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.cpp @@ -9,7 +9,7 @@ CppWinRTActivatableClassWithDPFactory(ColumnMajorUniformToLargestGridLayout) GlobalDependencyProperty ColumnMajorUniformToLargestGridLayoutProperties::s_ColumnSpacingProperty{ nullptr }; -GlobalDependencyProperty ColumnMajorUniformToLargestGridLayoutProperties::s_MaximumColumnsProperty{ nullptr }; +GlobalDependencyProperty ColumnMajorUniformToLargestGridLayoutProperties::s_MaxColumnsProperty{ nullptr }; GlobalDependencyProperty ColumnMajorUniformToLargestGridLayoutProperties::s_RowSpacingProperty{ nullptr }; ColumnMajorUniformToLargestGridLayoutProperties::ColumnMajorUniformToLargestGridLayoutProperties() @@ -24,32 +24,32 @@ void ColumnMajorUniformToLargestGridLayoutProperties::EnsureProperties() s_ColumnSpacingProperty = InitializeDependencyProperty( L"ColumnSpacing", - winrt::name_of(), + winrt::name_of(), winrt::name_of(), false /* isAttached */, - ValueHelper::BoxedDefaultValue(), + ValueHelper::BoxedDefaultValue(), winrt::PropertyChangedCallback(&OnColumnSpacingPropertyChanged)); } - if (!s_MaximumColumnsProperty) + if (!s_MaxColumnsProperty) { - s_MaximumColumnsProperty = + s_MaxColumnsProperty = InitializeDependencyProperty( - L"MaximumColumns", + L"MaxColumns", winrt::name_of(), winrt::name_of(), false /* isAttached */, ValueHelper::BoxedDefaultValue(), - winrt::PropertyChangedCallback(&OnMaximumColumnsPropertyChanged)); + winrt::PropertyChangedCallback(&OnMaxColumnsPropertyChanged)); } if (!s_RowSpacingProperty) { s_RowSpacingProperty = InitializeDependencyProperty( L"RowSpacing", - winrt::name_of(), + winrt::name_of(), winrt::name_of(), false /* isAttached */, - ValueHelper::BoxedDefaultValue(), + ValueHelper::BoxedDefaultValue(), winrt::PropertyChangedCallback(&OnRowSpacingPropertyChanged)); } } @@ -57,7 +57,7 @@ void ColumnMajorUniformToLargestGridLayoutProperties::EnsureProperties() void ColumnMajorUniformToLargestGridLayoutProperties::ClearProperties() { s_ColumnSpacingProperty = nullptr; - s_MaximumColumnsProperty = nullptr; + s_MaxColumnsProperty = nullptr; s_RowSpacingProperty = nullptr; } @@ -69,7 +69,7 @@ void ColumnMajorUniformToLargestGridLayoutProperties::OnColumnSpacingPropertyCha winrt::get_self(owner)->OnColumnSpacingPropertyChanged(args); } -void ColumnMajorUniformToLargestGridLayoutProperties::OnMaximumColumnsPropertyChanged( +void ColumnMajorUniformToLargestGridLayoutProperties::OnMaxColumnsPropertyChanged( winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args) { @@ -84,7 +84,7 @@ void ColumnMajorUniformToLargestGridLayoutProperties::OnMaximumColumnsPropertyCh return; } - winrt::get_self(owner)->OnMaximumColumnsPropertyChanged(args); + winrt::get_self(owner)->OnMaxColumnsPropertyChanged(args); } void ColumnMajorUniformToLargestGridLayoutProperties::OnRowSpacingPropertyChanged( @@ -95,34 +95,34 @@ void ColumnMajorUniformToLargestGridLayoutProperties::OnRowSpacingPropertyChange winrt::get_self(owner)->OnRowSpacingPropertyChanged(args); } -void ColumnMajorUniformToLargestGridLayoutProperties::ColumnSpacing(int value) +void ColumnMajorUniformToLargestGridLayoutProperties::ColumnSpacing(double value) { - static_cast(this)->SetValue(s_ColumnSpacingProperty, ValueHelper::BoxValueIfNecessary(value)); + static_cast(this)->SetValue(s_ColumnSpacingProperty, ValueHelper::BoxValueIfNecessary(value)); } -int ColumnMajorUniformToLargestGridLayoutProperties::ColumnSpacing() +double ColumnMajorUniformToLargestGridLayoutProperties::ColumnSpacing() { - return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_ColumnSpacingProperty)); + return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_ColumnSpacingProperty)); } -void ColumnMajorUniformToLargestGridLayoutProperties::MaximumColumns(int value) +void ColumnMajorUniformToLargestGridLayoutProperties::MaxColumns(int value) { int coercedValue = value; static_cast(this)->ValidateGreaterThanZero(coercedValue); - static_cast(this)->SetValue(s_MaximumColumnsProperty, ValueHelper::BoxValueIfNecessary(coercedValue)); + static_cast(this)->SetValue(s_MaxColumnsProperty, ValueHelper::BoxValueIfNecessary(coercedValue)); } -int ColumnMajorUniformToLargestGridLayoutProperties::MaximumColumns() +int ColumnMajorUniformToLargestGridLayoutProperties::MaxColumns() { - return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_MaximumColumnsProperty)); + return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_MaxColumnsProperty)); } -void ColumnMajorUniformToLargestGridLayoutProperties::RowSpacing(int value) +void ColumnMajorUniformToLargestGridLayoutProperties::RowSpacing(double value) { - static_cast(this)->SetValue(s_RowSpacingProperty, ValueHelper::BoxValueIfNecessary(value)); + static_cast(this)->SetValue(s_RowSpacingProperty, ValueHelper::BoxValueIfNecessary(value)); } -int ColumnMajorUniformToLargestGridLayoutProperties::RowSpacing() +double ColumnMajorUniformToLargestGridLayoutProperties::RowSpacing() { - return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_RowSpacingProperty)); + return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_RowSpacingProperty)); } diff --git a/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.h b/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.h index be47f1d050..c6eb89cb05 100644 --- a/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.h +++ b/dev/Generated/ColumnMajorUniformToLargestGridLayout.properties.h @@ -9,21 +9,21 @@ class ColumnMajorUniformToLargestGridLayoutProperties public: ColumnMajorUniformToLargestGridLayoutProperties(); - void ColumnSpacing(int value); - int ColumnSpacing(); + void ColumnSpacing(double value); + double ColumnSpacing(); - void MaximumColumns(int value); - int MaximumColumns(); + void MaxColumns(int value); + int MaxColumns(); - void RowSpacing(int value); - int RowSpacing(); + void RowSpacing(double value); + double RowSpacing(); static winrt::DependencyProperty ColumnSpacingProperty() { return s_ColumnSpacingProperty; } - static winrt::DependencyProperty MaximumColumnsProperty() { return s_MaximumColumnsProperty; } + static winrt::DependencyProperty MaxColumnsProperty() { return s_MaxColumnsProperty; } static winrt::DependencyProperty RowSpacingProperty() { return s_RowSpacingProperty; } static GlobalDependencyProperty s_ColumnSpacingProperty; - static GlobalDependencyProperty s_MaximumColumnsProperty; + static GlobalDependencyProperty s_MaxColumnsProperty; static GlobalDependencyProperty s_RowSpacingProperty; static void EnsureProperties(); @@ -33,7 +33,7 @@ class ColumnMajorUniformToLargestGridLayoutProperties winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args); - static void OnMaximumColumnsPropertyChanged( + static void OnMaxColumnsPropertyChanged( winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args); diff --git a/dev/Generated/RadioButtons.properties.cpp b/dev/Generated/RadioButtons.properties.cpp index a7e4c9e308..70f00b19a6 100644 --- a/dev/Generated/RadioButtons.properties.cpp +++ b/dev/Generated/RadioButtons.properties.cpp @@ -9,10 +9,11 @@ CppWinRTActivatableClassWithDPFactory(RadioButtons) GlobalDependencyProperty RadioButtonsProperties::s_HeaderProperty{ nullptr }; +GlobalDependencyProperty RadioButtonsProperties::s_HeaderTemplateProperty{ nullptr }; GlobalDependencyProperty RadioButtonsProperties::s_ItemsProperty{ nullptr }; GlobalDependencyProperty RadioButtonsProperties::s_ItemsSourceProperty{ nullptr }; GlobalDependencyProperty RadioButtonsProperties::s_ItemTemplateProperty{ nullptr }; -GlobalDependencyProperty RadioButtonsProperties::s_MaximumColumnsProperty{ nullptr }; +GlobalDependencyProperty RadioButtonsProperties::s_MaxColumnsProperty{ nullptr }; GlobalDependencyProperty RadioButtonsProperties::s_SelectedIndexProperty{ nullptr }; GlobalDependencyProperty RadioButtonsProperties::s_SelectedItemProperty{ nullptr }; @@ -35,6 +36,17 @@ void RadioButtonsProperties::EnsureProperties() ValueHelper::BoxedDefaultValue(), winrt::PropertyChangedCallback(&OnHeaderPropertyChanged)); } + if (!s_HeaderTemplateProperty) + { + s_HeaderTemplateProperty = + InitializeDependencyProperty( + L"HeaderTemplate", + winrt::name_of(), + winrt::name_of(), + false /* isAttached */, + ValueHelper::BoxedDefaultValue(), + winrt::PropertyChangedCallback(&OnHeaderTemplatePropertyChanged)); + } if (!s_ItemsProperty) { s_ItemsProperty = @@ -65,19 +77,19 @@ void RadioButtonsProperties::EnsureProperties() winrt::name_of(), winrt::name_of(), false /* isAttached */, - ValueHelper::BoxValueIfNecessary(winrt::RadioButtonsElementFactory{}), + ValueHelper::BoxValueIfNecessary(winrt::make()), winrt::PropertyChangedCallback(&OnItemTemplatePropertyChanged)); } - if (!s_MaximumColumnsProperty) + if (!s_MaxColumnsProperty) { - s_MaximumColumnsProperty = + s_MaxColumnsProperty = InitializeDependencyProperty( - L"MaximumColumns", + L"MaxColumns", winrt::name_of(), winrt::name_of(), false /* isAttached */, ValueHelper::BoxValueIfNecessary(1), - winrt::PropertyChangedCallback(&OnMaximumColumnsPropertyChanged)); + winrt::PropertyChangedCallback(&OnMaxColumnsPropertyChanged)); } if (!s_SelectedIndexProperty) { @@ -106,10 +118,11 @@ void RadioButtonsProperties::EnsureProperties() void RadioButtonsProperties::ClearProperties() { s_HeaderProperty = nullptr; + s_HeaderTemplateProperty = nullptr; s_ItemsProperty = nullptr; s_ItemsSourceProperty = nullptr; s_ItemTemplateProperty = nullptr; - s_MaximumColumnsProperty = nullptr; + s_MaxColumnsProperty = nullptr; s_SelectedIndexProperty = nullptr; s_SelectedItemProperty = nullptr; } @@ -122,6 +135,14 @@ void RadioButtonsProperties::OnHeaderPropertyChanged( winrt::get_self(owner)->OnPropertyChanged(args); } +void RadioButtonsProperties::OnHeaderTemplatePropertyChanged( + winrt::DependencyObject const& sender, + winrt::DependencyPropertyChangedEventArgs const& args) +{ + auto owner = sender.as(); + winrt::get_self(owner)->OnPropertyChanged(args); +} + void RadioButtonsProperties::OnItemsPropertyChanged( winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args) @@ -146,7 +167,7 @@ void RadioButtonsProperties::OnItemTemplatePropertyChanged( winrt::get_self(owner)->OnPropertyChanged(args); } -void RadioButtonsProperties::OnMaximumColumnsPropertyChanged( +void RadioButtonsProperties::OnMaxColumnsPropertyChanged( winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args) { @@ -180,6 +201,16 @@ winrt::IInspectable RadioButtonsProperties::Header() return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_HeaderProperty)); } +void RadioButtonsProperties::HeaderTemplate(winrt::DataTemplate const& value) +{ + static_cast(this)->SetValue(s_HeaderTemplateProperty, ValueHelper::BoxValueIfNecessary(value)); +} + +winrt::DataTemplate RadioButtonsProperties::HeaderTemplate() +{ + return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_HeaderTemplateProperty)); +} + void RadioButtonsProperties::Items(winrt::IVector const& value) { static_cast(this)->SetValue(s_ItemsProperty, ValueHelper>::BoxValueIfNecessary(value)); @@ -210,14 +241,14 @@ winrt::IInspectable RadioButtonsProperties::ItemTemplate() return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_ItemTemplateProperty)); } -void RadioButtonsProperties::MaximumColumns(int value) +void RadioButtonsProperties::MaxColumns(int value) { - static_cast(this)->SetValue(s_MaximumColumnsProperty, ValueHelper::BoxValueIfNecessary(value)); + static_cast(this)->SetValue(s_MaxColumnsProperty, ValueHelper::BoxValueIfNecessary(value)); } -int RadioButtonsProperties::MaximumColumns() +int RadioButtonsProperties::MaxColumns() { - return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_MaximumColumnsProperty)); + return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_MaxColumnsProperty)); } void RadioButtonsProperties::SelectedIndex(int value) diff --git a/dev/Generated/RadioButtons.properties.h b/dev/Generated/RadioButtons.properties.h index 5903d84566..201da5730f 100644 --- a/dev/Generated/RadioButtons.properties.h +++ b/dev/Generated/RadioButtons.properties.h @@ -12,6 +12,9 @@ class RadioButtonsProperties void Header(winrt::IInspectable const& value); winrt::IInspectable Header(); + void HeaderTemplate(winrt::DataTemplate const& value); + winrt::DataTemplate HeaderTemplate(); + void Items(winrt::IVector const& value); winrt::IVector Items(); @@ -21,8 +24,8 @@ class RadioButtonsProperties void ItemTemplate(winrt::IInspectable const& value); winrt::IInspectable ItemTemplate(); - void MaximumColumns(int value); - int MaximumColumns(); + void MaxColumns(int value); + int MaxColumns(); void SelectedIndex(int value); int SelectedIndex(); @@ -31,18 +34,20 @@ class RadioButtonsProperties winrt::IInspectable SelectedItem(); static winrt::DependencyProperty HeaderProperty() { return s_HeaderProperty; } + static winrt::DependencyProperty HeaderTemplateProperty() { return s_HeaderTemplateProperty; } static winrt::DependencyProperty ItemsProperty() { return s_ItemsProperty; } static winrt::DependencyProperty ItemsSourceProperty() { return s_ItemsSourceProperty; } static winrt::DependencyProperty ItemTemplateProperty() { return s_ItemTemplateProperty; } - static winrt::DependencyProperty MaximumColumnsProperty() { return s_MaximumColumnsProperty; } + static winrt::DependencyProperty MaxColumnsProperty() { return s_MaxColumnsProperty; } static winrt::DependencyProperty SelectedIndexProperty() { return s_SelectedIndexProperty; } static winrt::DependencyProperty SelectedItemProperty() { return s_SelectedItemProperty; } static GlobalDependencyProperty s_HeaderProperty; + static GlobalDependencyProperty s_HeaderTemplateProperty; static GlobalDependencyProperty s_ItemsProperty; static GlobalDependencyProperty s_ItemsSourceProperty; static GlobalDependencyProperty s_ItemTemplateProperty; - static GlobalDependencyProperty s_MaximumColumnsProperty; + static GlobalDependencyProperty s_MaxColumnsProperty; static GlobalDependencyProperty s_SelectedIndexProperty; static GlobalDependencyProperty s_SelectedItemProperty; @@ -58,6 +63,10 @@ class RadioButtonsProperties winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args); + static void OnHeaderTemplatePropertyChanged( + winrt::DependencyObject const& sender, + winrt::DependencyPropertyChangedEventArgs const& args); + static void OnItemsPropertyChanged( winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args); @@ -70,7 +79,7 @@ class RadioButtonsProperties winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args); - static void OnMaximumColumnsPropertyChanged( + static void OnMaxColumnsPropertyChanged( winrt::DependencyObject const& sender, winrt::DependencyPropertyChangedEventArgs const& args); diff --git a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp index 0d1f15fba7..b6ae136a31 100644 --- a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp +++ b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp @@ -15,7 +15,7 @@ winrt::Size ColumnMajorUniformToLargestGridLayout::MeasureOverride( { if (auto const children = context.Children()) { - auto const maxColumns = std::max(1, MaximumColumns()); + auto const maxColumns = std::max(1, MaxColumns()); MUX_ASSERT(maxColumns > 0); auto const maxItemsPerColumn = static_cast(std::ceil(static_cast(children.Size()) / static_cast(maxColumns))); @@ -44,9 +44,9 @@ winrt::Size ColumnMajorUniformToLargestGridLayout::MeasureOverride( static_cast(children.Size())); return winrt::Size( (m_largestChildSize.Width * actualColumnCount) + - (ColumnSpacing() * (actualColumnCount - 1)), + (static_cast(ColumnSpacing()) * (actualColumnCount - 1)), (m_largestChildSize.Height * maxItemsPerColumn) + - (RowSpacing() * (maxItemsPerColumn - 1)) + (static_cast(RowSpacing()) * (maxItemsPerColumn - 1)) ); } return winrt::Size(0, 0); @@ -58,14 +58,14 @@ winrt::Size ColumnMajorUniformToLargestGridLayout::ArrangeOverride( { if (auto const children = context.Children()) { - auto const maxColumns = std::max(1, MaximumColumns()); + auto const maxColumns = std::max(1, MaxColumns()); MUX_ASSERT(maxColumns > 0); auto const itemCount = children.Size(); auto const minitemsPerColumn = static_cast(std::floor(static_cast(itemCount) / static_cast(maxColumns))); auto const numberOfColumnsWithExtraElements = static_cast(itemCount % maxColumns); - auto const columnSpacing = ColumnSpacing(); - auto const rowSpacing = RowSpacing(); + auto const columnSpacing = static_cast(ColumnSpacing()); + auto const rowSpacing = static_cast(RowSpacing()); auto horizontalOffset = 0.0f; auto verticalOffset = 0.0f; @@ -133,7 +133,7 @@ void ColumnMajorUniformToLargestGridLayout::OnRowSpacingPropertyChanged(const wi InvalidateMeasure(); } -void ColumnMajorUniformToLargestGridLayout::OnMaximumColumnsPropertyChanged(const winrt::DependencyPropertyChangedEventArgs& args) +void ColumnMajorUniformToLargestGridLayout::OnMaxColumnsPropertyChanged(const winrt::DependencyPropertyChangedEventArgs& args) { InvalidateMeasure(); } @@ -146,7 +146,6 @@ void ColumnMajorUniformToLargestGridLayout::ValidateGreaterThanZero(int value) } } - //Testhooks helpers, only function while m_testHooksEnabled == true void ColumnMajorUniformToLargestGridLayout::SetTestHooksEnabled(bool enabled) diff --git a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h index a8ad9475b4..a92eebd7d3 100644 --- a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h +++ b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h @@ -24,7 +24,7 @@ class ColumnMajorUniformToLargestGridLayout : void OnColumnSpacingPropertyChanged(const winrt::DependencyPropertyChangedEventArgs&); void OnRowSpacingPropertyChanged(const winrt::DependencyPropertyChangedEventArgs&); - void OnMaximumColumnsPropertyChanged(const winrt::DependencyPropertyChangedEventArgs&); + void OnMaxColumnsPropertyChanged(const winrt::DependencyPropertyChangedEventArgs&); static void ValidateGreaterThanZero(int value); diff --git a/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs b/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs index ae8721d686..582246dfe2 100644 --- a/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs +++ b/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs @@ -28,17 +28,17 @@ public UIObject GetTestRadioButtons() } private UIObject TestRadioButtons; - public Edit GetMaximumColumnsTextBlock() + public Edit GetMaxColumnsTextBlock() { - return GetElement(ref MaximumColumnsTextBlock, "MaximumColumnsTextBlock"); + return GetElement(ref MaxColumnsTextBlock, "MaxColumnsTextBlock"); } - private Edit MaximumColumnsTextBlock; + private Edit MaxColumnsTextBlock; - public Button GetSetMaximumColumnsButton() + public Button GetSetMaxColumnsButton() { - return GetElement(ref SetMaximumColumnsButton, "SetMaximumColumnsButton"); + return GetElement(ref SetMaxColumnsButton, "SetMaxColumnsButton"); } - private Button SetMaximumColumnsButton; + private Button SetMaxColumnsButton; public Edit GetNumberOfItemsTextBlock() { @@ -64,6 +64,12 @@ public Button GetSelectByIndexButton() } private Button SelectByIndexButton; + public Button GetSelectByItemButton() + { + return GetElement(ref SelectByItemButton, "SelectByItemButton"); + } + private Button SelectByItemButton; + public Button GetInsertDisplayRadioButtonButton() { return GetElement(ref InsertDisplayRadioButtonButton, "InsertDisplayRadioButtonButton"); @@ -88,6 +94,12 @@ public CheckBox GetCustomDisabledCheckBox() } private CheckBox CustomDisabledCheckBox; + public CheckBox GetCustomCheckedCheckBox() + { + return GetElement(ref CustomCheckedCheckBox, "CustomCheckedCheckBox"); + } + private CheckBox CustomCheckedCheckBox; + public TextBlock GetSelectedIndexTextBlock() { return GetElement(ref SelectedIndexTextBlock, "SelectedIndexTextBlock"); @@ -99,7 +111,19 @@ public TextBlock GetSelectedItemTextBlock() return GetElement(ref SelectedItemTextBlock, "SelectedItemTextBlock"); } private TextBlock SelectedItemTextBlock; - + + public TextBlock GetSelectedPositionInSetTextBlock() + { + return GetElement(ref SelectedPositionInSetTextBlock, "SelectedPositionInSetTextBlock"); + } + private TextBlock SelectedPositionInSetTextBlock; + + public TextBlock GetSelectedSizeOfSetTextBlock() + { + return GetElement(ref SelectedSizeOfSetTextBlock, "SelectedSizeOfSetTextBlock"); + } + private TextBlock SelectedSizeOfSetTextBlock; + public CheckBox GetRadioButtonsHasFocusCheckBox() { return GetElement(ref RadioButtonsHasFocusCheckBox, "RadioButtonsHasFocusCheckBox"); diff --git a/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs b/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs index 570e7f9654..88d90dce4a 100644 --- a/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs +++ b/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs @@ -62,7 +62,7 @@ public void SelectionTest() RadioButton item1 = FindElement.ByName("Radio Button 1"); Verify.IsTrue(item1.IsSelected); - SelectByIndex(3); + SelectByItem(3); VerifySelectedIndex(3); RadioButton item3 = FindElement.ByName("Radio Button 3"); Verify.IsTrue(item3.IsSelected); @@ -71,6 +71,42 @@ public void SelectionTest() } } + [TestMethod] + public void SelectByItem() + { + if (!PlatformConfiguration.IsOsVersionGreaterThanOrEqual(OSVersion.Redstone4)) + { + Log.Warning("This test requires TrySetNewFocusedElement from RS4"); + return; + } + using (var setup = new TestSetupHelper("RadioButtons Tests")) + { + elements = new RadioButtonsTestPageElements(); + SetItemType(RadioButtonsSourceType.RadioButton); + foreach (RadioButtonsSourceLocation location in Enum.GetValues(typeof(RadioButtonsSourceLocation))) + { + SetSource(location); + foreach (RadioButtonsSourceType type in Enum.GetValues(typeof(RadioButtonsSourceType))) + { + if (location == RadioButtonsSourceLocation.Items && type == RadioButtonsSourceType.String) + { + // This is broken due to issue #1674. The items collection does not have a way to compare + // boxed strings for equality. + continue; + } + + SetItemType(type); + + SelectByItem(1); + VerifySelectedIndex(1); + + SelectByItem(3); + VerifySelectedIndex(3); + } + } + } + } + [TestMethod] public void FocusComingFromAnotherRepeaterTest() { @@ -501,10 +537,70 @@ public void ColumnsTest() } } + [TestMethod] + public void UIAProperties() + { + using (var setup = new TestSetupHelper("RadioButtons Tests")) + { + elements = new RadioButtonsTestPageElements(); + SetItemType(RadioButtonsSourceType.RadioButton); + SetSource(RadioButtonsSourceLocation.ItemSource); + + SelectByIndex(1); + VerifySelectedIndex(1); + VerifySelectedPositionInSet(2); + VerifySelectedSizeOfSet(10); + + SetNumberOfColumns(3); + VerifySelectedIndex(1); + VerifySelectedPositionInSet(2); + VerifySelectedSizeOfSet(10); + + InsertEnabledRadioButton(0); + VerifySelectedIndex(2); + VerifySelectedPositionInSet(3); + VerifySelectedSizeOfSet(11); + + InsertEnabledRadioButton(10); + VerifySelectedIndex(2); + VerifySelectedPositionInSet(3); + VerifySelectedSizeOfSet(12); + + SelectByIndex(10); + VerifySelectedIndex(10); + VerifySelectedPositionInSet(11); + VerifySelectedSizeOfSet(12); + + SetNumberOfItems(17); + SelectByIndex(16); + VerifySelectedIndex(16); + VerifySelectedPositionInSet(17); + VerifySelectedSizeOfSet(17); + } + } + + [TestMethod] + public void InsertedCheckedRadioButtonGetsSelection() + { + using (var setup = new TestSetupHelper("RadioButtons Tests")) + { + elements = new RadioButtonsTestPageElements(); + SetItemType(RadioButtonsSourceType.RadioButton); + SetSource(RadioButtonsSourceLocation.ItemSource); + + SelectByIndex(3); + VerifySelectedIndex(3); + + InsertEnabledRadioButton(6, /*isChecked*/true); + VerifySelectedIndex(6); + } + } + + void SetNumberOfColumns(int columns) { - elements.GetMaximumColumnsTextBlock().SetValue(columns.ToString()); - elements.GetSetMaximumColumnsButton().Click(); + elements.GetMaxColumnsTextBlock().SetValue(columns.ToString()); + elements.GetSetMaxColumnsButton().Click(); } void SetNumberOfItems(int items) @@ -539,19 +635,18 @@ void SetItemType(RadioButtonsSourceType type) } } - void InsertDisabledRadioButton(int index, string content = "Custom") + void InsertDisabledRadioButton(int index, bool isChecked = false, string content = "Custom") { - InsertRadioButton(index, true, content); + InsertRadioButton(index, true, isChecked, content); } - void InsertEnabledRadioButton(int index, string content = "Custom") + void InsertEnabledRadioButton(int index, bool isChecked = false, string content = "Custom") { - InsertRadioButton(index, false, content); + InsertRadioButton(index, false, isChecked, content); } - void InsertRadioButton(int index, bool disabled, string content = "Custom") + void InsertRadioButton(int index, bool disabled, bool isChecked = false, string content = "Custom") { - elements.GetCustomIndexTextBox().SetValue(index.ToString()); if (disabled) { elements.GetCustomDisabledCheckBox().Check(); @@ -560,8 +655,18 @@ void InsertRadioButton(int index, bool disabled, string content = "Custom") { elements.GetCustomDisabledCheckBox().Uncheck(); } - elements.GetCustomContentTextBox().SetValue(content); + if(isChecked) + { + elements.GetCustomCheckedCheckBox().Check(); + } + else + { + elements.GetCustomCheckedCheckBox().Uncheck(); + } + + elements.GetCustomIndexTextBox().SetValue(index.ToString()); + elements.GetCustomContentTextBox().SetValue(content); elements.GetInsertDisplayRadioButtonButton().Click(); } @@ -635,11 +740,26 @@ void SelectByIndex(int index) elements.GetSelectByIndexButton().Click(); } + void SelectByItem(int index) + { + SetIndexToSelect(index); + elements.GetSelectByItemButton().Click(); + } + void SetIndexToSelect(int index) { elements.GetIndexToSelectTextBlock().SetValue(index.ToString()); } + void VerifySelectedPositionInSet(int index) + { + Verify.AreEqual(index, Int32.Parse(elements.GetSelectedPositionInSetTextBlock().DocumentText)); + } + void VerifySelectedSizeOfSet(int index) + { + Verify.AreEqual(index, Int32.Parse(elements.GetSelectedSizeOfSetTextBlock().DocumentText)); + } + void VerifySelectedFocusedIndex(int index) { VerifySelectedIndex(index); diff --git a/dev/RadioButtons/RadioButtons.cpp b/dev/RadioButtons/RadioButtons.cpp index 370bc84501..a6d2165aca 100644 --- a/dev/RadioButtons/RadioButtons.cpp +++ b/dev/RadioButtons/RadioButtons.cpp @@ -115,6 +115,7 @@ void RadioButtons::OnRepeaterLoaded(const winrt::IInspectable&, const winrt::Rou AttachToLayoutChanged(); } + UpdateSelectedItem(); UpdateSelectedIndex(); OnRepeaterCollectionChanged(nullptr, nullptr); } @@ -239,6 +240,12 @@ void RadioButtons::OnRepeaterElementPrepared(const winrt::ItemsRepeater&, const childHandlers->uncheckedRevoker = toggleButton.Unchecked(winrt::auto_revoke, { this, &RadioButtons::OnChildUnchecked }); toggleButton.SetValue(s_childHandlersProperty, childHandlers.as()); + + // If the developer adds a checked toggle button to the collection, update selection to this item. + if (SharedHelpers::IsTrue(toggleButton.IsChecked())) + { + Select(args.Index()); + } } if (auto const repeater = m_repeater.get()) { @@ -256,6 +263,15 @@ void RadioButtons::OnRepeaterElementClearing(const winrt::ItemsRepeater&, const if (auto const element = args.Element()) { element.SetValue(s_childHandlersProperty, nullptr); + + // If the removed element was the selected one, update selection to -1 + if (auto const elementAsToggle = element.try_as()) + { + if (SharedHelpers::IsTrue(elementAsToggle.IsChecked())) + { + Select(-1); + } + } } } @@ -264,10 +280,15 @@ void RadioButtons::OnRepeaterElementIndexChanged(const winrt::ItemsRepeater&, co if (auto const element = args.Element()) { element.SetValue(winrt::AutomationProperties::PositionInSetProperty(), box_value(args.NewIndex() + 1)); - } - if (args.OldIndex() == m_selectedIndex) - { - Select(args.NewIndex()); + + // When the selected item's index changes, update selection to match + if (auto const elementAsToggle = element.try_as()) + { + if (SharedHelpers::IsTrue(elementAsToggle.IsChecked())) + { + Select(args.NewIndex()); + } + } } } @@ -280,9 +301,9 @@ void RadioButtons::OnRepeaterCollectionChanged(const winrt::IInspectable&, const auto const count = itemSourceView.Count(); for (auto index = 0; index < count; index++) { - if (auto const radioButton = repeater.TryGetElement(index)) + if (auto const element = repeater.TryGetElement(index)) { - radioButton.SetValue(winrt::AutomationProperties::SizeOfSetProperty(), box_value(count)); + element.SetValue(winrt::AutomationProperties::SizeOfSetProperty(), box_value(count)); } } } @@ -426,6 +447,19 @@ void RadioButtons::OnPropertyChanged(const winrt::DependencyPropertyChangedEvent { UpdateSelectedIndex(); } + else if (property == s_SelectedItemProperty) + { + UpdateSelectedItem(); + } +} + +winrt::UIElement RadioButtons::ContainerFromIndex(int index) +{ + if (auto const repeater = m_repeater.get()) + { + return repeater.TryGetElement(index); + } + return nullptr; } void RadioButtons::UpdateItemsSource() @@ -463,13 +497,21 @@ void RadioButtons::UpdateSelectedIndex() } } -winrt::UIElement RadioButtons::ContainerFromIndex(int index) +void RadioButtons::UpdateSelectedItem() { - if (auto const repeater = m_repeater.get()) + if (!m_currentlySelecting) { - return repeater.TryGetElement(index); + if (auto const repeater = m_repeater.get()) + { + if (auto const itemsSourceView = repeater.ItemsSourceView()) + { + if (auto const inspectingDataSource = static_cast(winrt::get_self(itemsSourceView))) + { + Select(inspectingDataSource->IndexOf(SelectedItem())); + } + } + } } - return nullptr; } // Test Hooks helpers, only function when m_testHooksEnabled == true diff --git a/dev/RadioButtons/RadioButtons.h b/dev/RadioButtons/RadioButtons.h index 1bab472ce3..62707c8eef 100644 --- a/dev/RadioButtons/RadioButtons.h +++ b/dev/RadioButtons/RadioButtons.h @@ -5,6 +5,7 @@ #include "common.h" +#include "RadioButtonsElementFactory.h" #include "RadioButtons.g.h" #include "RadioButtons.properties.h" #include "ColumnMajorUniformToLargestGridLayout.h" @@ -60,6 +61,7 @@ class RadioButtons : winrt::IInspectable GetItemsSource(); void UpdateSelectedIndex(); + void UpdateSelectedItem(); void Select(int index); winrt::IInspectable GetDataAtIndex(int index, bool containerIsChecked); diff --git a/dev/RadioButtons/RadioButtons.idl b/dev/RadioButtons/RadioButtons.idl index cd49f12f46..9ce5d22064 100644 --- a/dev/RadioButtons/RadioButtons.idl +++ b/dev/RadioButtons/RadioButtons.idl @@ -1,7 +1,7 @@ namespace MU_XC_NAMESPACE { -[WUXC_VERSION_PREVIEW] +[WUXC_VERSION_MUXONLY] [webhosthidden] [contentproperty("Items")] [MUX_PROPERTY_CHANGED_CALLBACK(TRUE)] @@ -12,27 +12,30 @@ unsealed runtimeclass RadioButtons : Windows.UI.Xaml.Controls.Control Object ItemsSource; Windows.Foundation.Collections.IVector Items{ get; }; - [MUX_DEFAULT_VALUE("winrt::RadioButtonsElementFactory{}")] + [MUX_DEFAULT_VALUE("winrt::make()")] Object ItemTemplate; Windows.UI.Xaml.UIElement ContainerFromIndex(Int32 index); [MUX_DEFAULT_VALUE("-1")] Int32 SelectedIndex; - Object SelectedItem{ get; }; + Object SelectedItem; event Windows.UI.Xaml.Controls.SelectionChangedEventHandler SelectionChanged; [MUX_DEFAULT_VALUE("1")] - Int32 MaximumColumns; + Int32 MaxColumns; + Object Header; + Windows.UI.Xaml.DataTemplate HeaderTemplate; static Windows.UI.Xaml.DependencyProperty ItemsSourceProperty{ get; }; static Windows.UI.Xaml.DependencyProperty ItemsProperty{ get; }; static Windows.UI.Xaml.DependencyProperty ItemTemplateProperty{ get; }; static Windows.UI.Xaml.DependencyProperty SelectedIndexProperty{ get; }; static Windows.UI.Xaml.DependencyProperty SelectedItemProperty{ get; }; - static Windows.UI.Xaml.DependencyProperty MaximumColumnsProperty{ get; }; + static Windows.UI.Xaml.DependencyProperty MaxColumnsProperty{ get; }; static Windows.UI.Xaml.DependencyProperty HeaderProperty{ get; }; + static Windows.UI.Xaml.DependencyProperty HeaderTemplateProperty{ get; }; } } diff --git a/dev/RadioButtons/RadioButtons.xaml b/dev/RadioButtons/RadioButtons.xaml index f3d2b9b9f5..6b289ce915 100644 --- a/dev/RadioButtons/RadioButtons.xaml +++ b/dev/RadioButtons/RadioButtons.xaml @@ -15,11 +15,13 @@ - + diff --git a/dev/RadioButtons/RadioButtonsElementFactory.cpp b/dev/RadioButtons/RadioButtonsElementFactory.cpp index 311ee4ff74..4046b65b0d 100644 --- a/dev/RadioButtons/RadioButtonsElementFactory.cpp +++ b/dev/RadioButtons/RadioButtonsElementFactory.cpp @@ -7,10 +7,6 @@ #include "Utils.h" #include "RadioButtonsElementFactory.h" -CppWinRTActivatableClassWithBasicFactory(RadioButtonsElementFactory); - -// IItemsControlOverrides - RadioButtonsElementFactory::RadioButtonsElementFactory() { } diff --git a/dev/RadioButtons/RadioButtonsElementFactory.h b/dev/RadioButtons/RadioButtonsElementFactory.h index 3411529362..94a7130563 100644 --- a/dev/RadioButtons/RadioButtonsElementFactory.h +++ b/dev/RadioButtons/RadioButtonsElementFactory.h @@ -3,12 +3,10 @@ #pragma once #include "common.h" -#include "RadioButtonsElementFactory.g.h" -#include "RadioButtonsElementFactory.properties.h" #include "ElementFactory.h" class RadioButtonsElementFactory : - public ReferenceTracker + public winrt::implements { public: RadioButtonsElementFactory(); diff --git a/dev/RadioButtons/RadioButtonsPrimitives.idl b/dev/RadioButtons/RadioButtonsPrimitives.idl index e0c6d41585..0019863fbe 100644 --- a/dev/RadioButtons/RadioButtonsPrimitives.idl +++ b/dev/RadioButtons/RadioButtonsPrimitives.idl @@ -1,14 +1,7 @@ namespace MU_XCP_NAMESPACE { -[WUXC_VERSION_PREVIEW] -[webhosthidden] -[default_interface] -unsealed runtimeclass RadioButtonsElementFactory : MU_XC_NAMESPACE.ElementFactory -{ - RadioButtonsElementFactory(); -} -[WUXC_VERSION_PREVIEW] +[WUXC_VERSION_MUXONLY] [webhosthidden] [default_interface] unsealed runtimeclass ColumnMajorUniformToLargestGridLayout : MU_XC_NAMESPACE.NonVirtualizingLayout @@ -17,15 +10,15 @@ unsealed runtimeclass ColumnMajorUniformToLargestGridLayout : MU_XC_NAMESPACE.No [MUX_PROPERTY_CHANGED_CALLBACK(TRUE)] [MUX_PROPERTY_VALIDATION_CALLBACK("ValidateGreaterThanZero")] - Int32 MaximumColumns{ get; set; }; - static Windows.UI.Xaml.DependencyProperty MaximumColumnsProperty{ get; }; + Int32 MaxColumns{ get; set; }; + static Windows.UI.Xaml.DependencyProperty MaxColumnsProperty{ get; }; [MUX_PROPERTY_CHANGED_CALLBACK(TRUE)] - Int32 ColumnSpacing{ get; set; }; + Double ColumnSpacing{ get; set; }; static Windows.UI.Xaml.DependencyProperty ColumnSpacingProperty{ get; }; [MUX_PROPERTY_CHANGED_CALLBACK(TRUE)] - Int32 RowSpacing{ get; set; }; + Double RowSpacing{ get; set; }; static Windows.UI.Xaml.DependencyProperty RowSpacingProperty{ get; }; } diff --git a/dev/RadioButtons/TestUI/RadioButtonsPage.xaml b/dev/RadioButtons/TestUI/RadioButtonsPage.xaml index 7c05ce05d9..8f532703d4 100644 --- a/dev/RadioButtons/TestUI/RadioButtonsPage.xaml +++ b/dev/RadioButtons/TestUI/RadioButtonsPage.xaml @@ -67,9 +67,9 @@ - - -