diff --git a/src/MergedWinMD/Directory.Build.props b/src/MergedWinMD/Directory.Build.props
index 1021695240..fd7ced7281 100644
--- a/src/MergedWinMD/Directory.Build.props
+++ b/src/MergedWinMD/Directory.Build.props
@@ -7,6 +7,15 @@
+
+
+ $(MSBuildThisFileDirectory)..\packages
+
+
+ true
+
+
false
diff --git a/src/Packages.props b/src/Packages.props
index 657871cf52..5dffcba1b7 100644
--- a/src/Packages.props
+++ b/src/Packages.props
@@ -26,7 +26,7 @@
-
+
diff --git a/src/controls/dev/CommonStyles/Hyperlink_themeresources.xaml b/src/controls/dev/CommonStyles/Hyperlink_themeresources.xaml
index 801fc09762..9755333d16 100644
--- a/src/controls/dev/CommonStyles/Hyperlink_themeresources.xaml
+++ b/src/controls/dev/CommonStyles/Hyperlink_themeresources.xaml
@@ -7,9 +7,9 @@
-
-
-
+
+
+
@@ -18,4 +18,4 @@
False
-
\ No newline at end of file
+
diff --git a/src/controls/dev/CommonStyles/TestUI/FlatItemsControlPage.xaml.cs b/src/controls/dev/CommonStyles/TestUI/FlatItemsControlPage.xaml.cs
index a221385c08..765139a972 100644
--- a/src/controls/dev/CommonStyles/TestUI/FlatItemsControlPage.xaml.cs
+++ b/src/controls/dev/CommonStyles/TestUI/FlatItemsControlPage.xaml.cs
@@ -18,7 +18,7 @@ namespace MUXControlsTestApp
{
public sealed partial class FlatItemsControlPage : TestPage
{
- private ObservableCollection _colRecipes = null;
+ private ObservableCollection _colEntities = null;
private ItemsPanelTemplate _modernPanelTemplate = null;
private DataTemplate[] _itemTemplates = new DataTemplate[3];
@@ -31,13 +31,13 @@ public FlatItemsControlPage()
private void FlatItemsControlPage_Loaded(object sender, RoutedEventArgs e)
{
- _colRecipes = new ObservableCollection();
+ _colEntities = new ObservableCollection();
for (int itemIndex = 0; itemIndex < 250; itemIndex++)
{
BitmapImage bitmapImage = GetBitmapImage(itemIndex % 126 + 1);
- _colRecipes.Add(new Recipe()
+ _colEntities.Add(new Entity()
{
BitmapImage = bitmapImage,
Id = itemIndex
@@ -50,7 +50,7 @@ private void FlatItemsControlPage_Loaded(object sender, RoutedEventArgs e)
UpdateItemsControlXYFocusKeyboardNavigation();
UpdateItemsPanelType();
- itemsControl.ItemsSource = _colRecipes;
+ itemsControl.ItemsSource = _colEntities;
}
private void UpdateItemsPanelType()
@@ -260,9 +260,9 @@ private void UpdateDataSourceItemCount()
{
txtDataSourceItemCount.Text = "0";
}
- else if (itemsControl.ItemsSource == _colRecipes)
+ else if (itemsControl.ItemsSource == _colEntities)
{
- txtDataSourceItemCount.Text = _colRecipes.Count.ToString();
+ txtDataSourceItemCount.Text = _colEntities.Count.ToString();
}
}
}
@@ -283,17 +283,17 @@ private void DataSourceAddItem()
{
if (itemsControl != null && itemsControl.ItemsSource != null)
{
- if (itemsControl.ItemsSource == _colRecipes)
+ if (itemsControl.ItemsSource == _colEntities)
{
- BitmapImage bitmapImage = GetBitmapImage(_colRecipes.Count % 126 + 1);
+ BitmapImage bitmapImage = GetBitmapImage(_colEntities.Count % 126 + 1);
- var recipe = new Recipe()
+ var entity = new Entity()
{
BitmapImage = bitmapImage,
- Id = _colRecipes.Count
+ Id = _colEntities.Count
};
- _colRecipes.Add(recipe);
+ _colEntities.Add(entity);
}
}
}
@@ -310,17 +310,17 @@ private void DataSourceInsertItem(int newItemIndex)
{
if (itemsControl != null && itemsControl.ItemsSource != null)
{
- if (itemsControl.ItemsSource == _colRecipes)
+ if (itemsControl.ItemsSource == _colEntities)
{
- BitmapImage bitmapImage = GetBitmapImage(_colRecipes.Count % 126 + 1);
+ BitmapImage bitmapImage = GetBitmapImage(_colEntities.Count % 126 + 1);
- var recipe = new Recipe()
+ var entity = new Entity()
{
BitmapImage = bitmapImage,
- Id = _colRecipes.Count
+ Id = _colEntities.Count
};
- _colRecipes.Insert(newItemIndex, recipe);
+ _colEntities.Insert(newItemIndex, entity);
}
}
}
@@ -337,9 +337,9 @@ private void DataSourceRemoveAllItems()
{
if (itemsControl != null && itemsControl.ItemsSource != null)
{
- if (itemsControl.ItemsSource == _colRecipes)
+ if (itemsControl.ItemsSource == _colEntities)
{
- _colRecipes.Clear();
+ _colEntities.Clear();
}
}
}
@@ -356,9 +356,9 @@ private void DataSourceRemoveItem(int oldItemIndex)
{
if (itemsControl != null && itemsControl.ItemsSource != null)
{
- if (itemsControl.ItemsSource == _colRecipes)
+ if (itemsControl.ItemsSource == _colEntities)
{
- _colRecipes.RemoveAt(oldItemIndex);
+ _colEntities.RemoveAt(oldItemIndex);
}
}
}
@@ -375,17 +375,17 @@ private void DataSourceReplaceItem(int itemIndex)
{
if (itemsControl != null && itemsControl.ItemsSource != null)
{
- if (itemsControl.ItemsSource == _colRecipes)
+ if (itemsControl.ItemsSource == _colEntities)
{
- BitmapImage bitmapImage = GetBitmapImage(_colRecipes.Count % 126 + 1);
+ BitmapImage bitmapImage = GetBitmapImage(_colEntities.Count % 126 + 1);
- var recipe = new Recipe()
+ var entity = new Entity()
{
BitmapImage = bitmapImage,
- Id = _colRecipes.Count
+ Id = _colEntities.Count
};
- _colRecipes[itemIndex] = recipe;
+ _colEntities[itemIndex] = entity;
}
}
}
@@ -595,7 +595,7 @@ private void BtnSetItemsPanelOrientation_Click(object sender, RoutedEventArgs e)
}
}
- itemsControl.ItemsSource = _colRecipes;
+ itemsControl.ItemsSource = _colEntities;
}
}
@@ -659,31 +659,31 @@ private void BtnDataSourceSetItemCount_Click(object sender, RoutedEventArgs e)
{
int newItemCount = int.Parse(txtDataSourceItemCount.Text);
- if (itemsControl.ItemsSource == _colRecipes)
+ if (itemsControl.ItemsSource == _colEntities)
{
- if (_colRecipes.Count < newItemCount)
+ if (_colEntities.Count < newItemCount)
{
- var colRecipesEnd = new List();
+ var colEntitiesEnd = new List();
- for (int itemIndex = 0; itemIndex < newItemCount - _colRecipes.Count; itemIndex++)
+ for (int itemIndex = 0; itemIndex < newItemCount - _colEntities.Count; itemIndex++)
{
BitmapImage bitmapImage = GetBitmapImage(itemIndex % 126 + 1);
- colRecipesEnd.Add(new Recipe()
+ colEntitiesEnd.Add(new Entity()
{
BitmapImage = bitmapImage,
Id = itemIndex
});
}
- _colRecipes = new ObservableCollection(_colRecipes.Concat(colRecipesEnd));
+ _colEntities = new ObservableCollection(_colEntities.Concat(colEntitiesEnd));
}
- else if (_colRecipes.Count > newItemCount)
+ else if (_colEntities.Count > newItemCount)
{
- _colRecipes = new ObservableCollection(_colRecipes.Take(newItemCount));
+ _colEntities = new ObservableCollection(_colEntities.Take(newItemCount));
}
- itemsControl.ItemsSource = _colRecipes;
+ itemsControl.ItemsSource = _colEntities;
}
}
}
diff --git a/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml b/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml
index e82cd92405..ee6246fff6 100644
--- a/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml
+++ b/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml
@@ -234,7 +234,7 @@
@@ -244,14 +244,21 @@
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -260,7 +267,11 @@
ColumnDefinitions="*">
-
+
+
+
+
+
diff --git a/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml.cs b/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml.cs
index a2912f7f90..9470660100 100644
--- a/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml.cs
+++ b/src/controls/dev/CommonStyles/TestUI/ListViewBasePage.xaml.cs
@@ -18,15 +18,61 @@ namespace MUXControlsTestApp
{
public sealed partial class ListViewBasePage : TestPage
{
- private ObservableCollection _colRecipes = null;
+ private enum QueuedOperationType
+ {
+ DataSourceAdd,
+ DataSourceInsert,
+ DataSourceRemove,
+ DataSourceRemoveAll,
+ DataSourceReplace,
+ DataSourceRaiseResetNotification
+ }
+
+ private class QueuedOperation
+ {
+ public QueuedOperation(QueuedOperationType type)
+ {
+ this.Type = type;
+ }
+
+ public QueuedOperation(QueuedOperationType type, double value)
+ {
+ this.Type = type;
+ this.DoubleValue = value;
+ }
+
+ public QueuedOperation(QueuedOperationType type, int value)
+ {
+ this.Type = type;
+ this.IntValue = value;
+ }
+
+ public QueuedOperation(QueuedOperationType type, string value)
+ {
+ this.Type = type;
+ this.StringValue = value;
+ }
+
+ public QueuedOperationType Type { get; set; }
+ public double DoubleValue { get; set; }
+ public int IntValue { get; set; }
+ public string StringValue { get; set; }
+ }
+
+ private EntityObservableCollection _colEntities = null;
private ListViewBase _listViewBase = null;
private ScrollViewer _scrollViewer = null;
private ItemsPanelTemplate _modernPanelTemplate = null;
+ private List _lstQueuedOperations = new List();
+ private DispatcherTimer _queuedOperationsTimer = new DispatcherTimer();
public ListViewBasePage()
{
this.InitializeComponent();
+ _queuedOperationsTimer.Interval = new TimeSpan(0, 0, 10 /*sec*/);
+ _queuedOperationsTimer.Tick += QueuedOperationsTimer_Tick;
+
Loaded += ListViewBasePage_Loaded;
}
@@ -55,13 +101,13 @@ private void ListViewBasePage_Loaded(object sender, RoutedEventArgs e)
{
_scrollViewer = FindElementOfTypeInSubtree(_listViewBase);
- _colRecipes = new ObservableCollection();
+ _colEntities = new EntityObservableCollection();
for (int itemIndex = 0; itemIndex < 250; itemIndex++)
{
BitmapImage bitmapImage = GetBitmapImage(itemIndex % 126 + 1);
- _colRecipes.Add(new Recipe()
+ _colEntities.Add(new Entity()
{
BitmapImage = bitmapImage,
Id = itemIndex
@@ -71,7 +117,7 @@ private void ListViewBasePage_Loaded(object sender, RoutedEventArgs e)
UpdateItemsPanelType();
UpdateListViewBaseSingleSelectionFollowsFocus();
- _listViewBase.ItemsSource = _colRecipes;
+ _listViewBase.ItemsSource = _colEntities;
}
// Workaround to avoid the ListViewBase not being scrollable after an ItemsPanel change to VirtualizingStackPanel.
@@ -503,9 +549,9 @@ private void UpdateDataSourceItemCount()
{
txtDataSourceItemCount.Text = "0";
}
- else if (_listViewBase.ItemsSource == _colRecipes)
+ else if (_listViewBase.ItemsSource == _colEntities)
{
- txtDataSourceItemCount.Text = _colRecipes.Count.ToString();
+ txtDataSourceItemCount.Text = _colEntities.Count.ToString();
}
}
}
@@ -526,17 +572,17 @@ private void DataSourceAddItem()
{
if (_listViewBase != null && _listViewBase.ItemsSource != null)
{
- if (_listViewBase.ItemsSource == _colRecipes)
+ if (_listViewBase.ItemsSource == _colEntities)
{
- BitmapImage bitmapImage = GetBitmapImage(_colRecipes.Count % 126 + 1);
+ BitmapImage bitmapImage = GetBitmapImage(_colEntities.Count % 126 + 1);
- var recipe = new Recipe()
+ var entity = new Entity()
{
BitmapImage = bitmapImage,
- Id = _colRecipes.Count
+ Id = _colEntities.Count
};
- _colRecipes.Add(recipe);
+ _colEntities.Add(entity);
}
}
}
@@ -553,17 +599,17 @@ private void DataSourceInsertItem(int newItemIndex)
{
if (_listViewBase != null && _listViewBase.ItemsSource != null)
{
- if (_listViewBase.ItemsSource == _colRecipes)
+ if (_listViewBase.ItemsSource == _colEntities)
{
- BitmapImage bitmapImage = GetBitmapImage(_colRecipes.Count % 126 + 1);
+ BitmapImage bitmapImage = GetBitmapImage(_colEntities.Count % 126 + 1);
- var recipe = new Recipe()
+ var entity = new Entity()
{
BitmapImage = bitmapImage,
- Id = _colRecipes.Count
+ Id = _colEntities.Count
};
- _colRecipes.Insert(newItemIndex, recipe);
+ _colEntities.Insert(newItemIndex, entity);
}
}
}
@@ -580,9 +626,9 @@ private void DataSourceRemoveAllItems()
{
if (_listViewBase != null && _listViewBase.ItemsSource != null)
{
- if (_listViewBase.ItemsSource == _colRecipes)
+ if (_listViewBase.ItemsSource == _colEntities)
{
- _colRecipes.Clear();
+ _colEntities.Clear();
}
}
}
@@ -599,9 +645,9 @@ private void DataSourceRemoveItem(int oldItemIndex)
{
if (_listViewBase != null && _listViewBase.ItemsSource != null)
{
- if (_listViewBase.ItemsSource == _colRecipes)
+ if (_listViewBase.ItemsSource == _colEntities)
{
- _colRecipes.RemoveAt(oldItemIndex);
+ _colEntities.RemoveAt(oldItemIndex);
}
}
}
@@ -618,17 +664,17 @@ private void DataSourceReplaceItem(int itemIndex)
{
if (_listViewBase != null && _listViewBase.ItemsSource != null)
{
- if (_listViewBase.ItemsSource == _colRecipes)
+ if (_listViewBase.ItemsSource == _colEntities)
{
- BitmapImage bitmapImage = GetBitmapImage(_colRecipes.Count % 126 + 1);
+ BitmapImage bitmapImage = GetBitmapImage(_colEntities.Count % 126 + 1);
- var recipe = new Recipe()
+ var entity = new Entity()
{
BitmapImage = bitmapImage,
- Id = _colRecipes.Count
+ Id = _colEntities.Count
};
- _colRecipes[itemIndex] = recipe;
+ _colEntities[itemIndex] = entity;
}
}
}
@@ -639,6 +685,14 @@ private void DataSourceReplaceItem(int itemIndex)
}
}
+ private void DataSourceRaiseResetNotification()
+ {
+ if (_colEntities != null)
+ {
+ _colEntities.RaiseResetNotification();
+ }
+ }
+
private void ListViewBase_ItemClick(object sender, ItemClickEventArgs e)
{
try
@@ -817,7 +871,7 @@ private void BtnSetItemsPanelOrientation_Click(object sender, RoutedEventArgs e)
}
}
- _listViewBase.ItemsSource = _colRecipes;
+ _listViewBase.ItemsSource = _colEntities;
// _listViewBase.ItemsPanelRoot is only updated asynchronously.
_ = this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Low, UpdateScrollViewerScrollOrientation);
@@ -979,31 +1033,31 @@ private void BtnDataSourceSetItemCount_Click(object sender, RoutedEventArgs e)
{
int newItemCount = int.Parse(txtDataSourceItemCount.Text);
- if (_listViewBase.ItemsSource == _colRecipes)
+ if (_listViewBase.ItemsSource == _colEntities)
{
- if (_colRecipes.Count < newItemCount)
+ if (_colEntities.Count < newItemCount)
{
- var colRecipesEnd = new List();
+ var colEntitiesEnd = new List();
- for (int itemIndex = 0; itemIndex < newItemCount - _colRecipes.Count; itemIndex++)
+ for (int itemIndex = 0; itemIndex < newItemCount - _colEntities.Count; itemIndex++)
{
BitmapImage bitmapImage = GetBitmapImage(itemIndex % 126 + 1);
- colRecipesEnd.Add(new Recipe()
+ colEntitiesEnd.Add(new Entity()
{
BitmapImage = bitmapImage,
Id = itemIndex
});
}
- _colRecipes = new ObservableCollection(_colRecipes.Concat(colRecipesEnd));
+ _colEntities = new EntityObservableCollection(_colEntities.Collection.Concat(colEntitiesEnd));
}
- else if (_colRecipes.Count > newItemCount)
+ else if (_colEntities.Count > newItemCount)
{
- _colRecipes = new ObservableCollection(_colRecipes.Take(newItemCount));
+ _colEntities = new EntityObservableCollection(_colEntities.Collection.Take(newItemCount));
}
- _listViewBase.ItemsSource = _colRecipes;
+ _listViewBase.ItemsSource = _colEntities;
}
}
}
@@ -1020,6 +1074,12 @@ private void BtnDataSourceAddItem_Click(object sender, RoutedEventArgs e)
DataSourceAddItem();
}
+ private void BtnQueueDataSourceAddItem_Click(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage("Queued DataSourceAdd");
+ EnqueueOperation(QueuedOperationType.DataSourceAdd);
+ }
+
private void BtnDataSourceInsertItem_Click(object sender, RoutedEventArgs e)
{
try
@@ -1039,12 +1099,49 @@ private void BtnDataSourceInsertItem_Click(object sender, RoutedEventArgs e)
}
}
+ private void BtnQueueDataSourceInsertItem_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (txtDataSourceItemIndex != null)
+ {
+ int newItemIndex = int.Parse(txtDataSourceItemIndex.Text);
+
+ AppendEventMessage("Queued DataSourceInsert " + newItemIndex);
+ EnqueueOperation(new QueuedOperation(QueuedOperationType.DataSourceInsert, newItemIndex));
+ }
+ }
+ catch (Exception ex)
+ {
+ txtExceptionReport.Text = ex.ToString();
+ AppendEventMessage(ex.ToString());
+ }
+ }
+
private void BtnDataSourceRemoveAllItems_Click(object sender, RoutedEventArgs e)
{
AppendEventMessage("DataSourceRemoveAll");
DataSourceRemoveAllItems();
}
+ private void BtnQueueDataSourceRemoveAllItems_Click(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage("Queued DataSourceRemoveAll");
+ EnqueueOperation(QueuedOperationType.DataSourceRemoveAll);
+ }
+
+ private void BtnDataSourceRaiseResetNotification_Click(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage("DataSourceRaiseResetNotification");
+ DataSourceRaiseResetNotification();
+ }
+
+ private void BtnQueueDataSourceRaiseResetNotification_Click(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage("Queued DataSourceRaiseResetNotification");
+ EnqueueOperation(QueuedOperationType.DataSourceRaiseResetNotification);
+ }
+
private void BtnDataSourceRemoveItem_Click(object sender, RoutedEventArgs e)
{
try
@@ -1064,6 +1161,25 @@ private void BtnDataSourceRemoveItem_Click(object sender, RoutedEventArgs e)
}
}
+ private void BtnQueueDataSourceRemoveItem_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (txtDataSourceItemIndex != null)
+ {
+ int oldItemIndex = int.Parse(txtDataSourceItemIndex.Text);
+
+ AppendEventMessage("Queued DataSourceRemove " + oldItemIndex);
+ EnqueueOperation(new QueuedOperation(QueuedOperationType.DataSourceRemove, oldItemIndex));
+ }
+ }
+ catch (Exception ex)
+ {
+ txtExceptionReport.Text = ex.ToString();
+ AppendEventMessage(ex.ToString());
+ }
+ }
+
private void BtnDataSourceReplaceItem_Click(object sender, RoutedEventArgs e)
{
try
@@ -1083,6 +1199,25 @@ private void BtnDataSourceReplaceItem_Click(object sender, RoutedEventArgs e)
}
}
+ private void BtnQueueDataSourceReplaceItem_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (txtDataSourceItemIndex != null)
+ {
+ int itemIndex = int.Parse(txtDataSourceItemIndex.Text);
+
+ AppendEventMessage("Queued DataSourceReplace " + itemIndex);
+ EnqueueOperation(new QueuedOperation(QueuedOperationType.DataSourceReplace, itemIndex));
+ }
+ }
+ catch (Exception ex)
+ {
+ txtExceptionReport.Text = ex.ToString();
+ AppendEventMessage(ex.ToString());
+ }
+ }
+
private void ChkListViewBaseAllowDrop_IsCheckedChanged(object sender, RoutedEventArgs e)
{
try
@@ -1217,7 +1352,10 @@ private void ChkLogs_Unchecked(object sender, RoutedEventArgs e)
private void AppendEventMessage(string eventMessage)
{
- lstLogs.Items.Add(eventMessage);
+ if (chkLog.IsChecked == true)
+ {
+ lstLogs.Items.Add(eventMessage);
+ }
}
private void BtnClearExceptionReport_Click(object sender, RoutedEventArgs e)
@@ -1259,5 +1397,62 @@ private static T FindElementOfTypeInSubtree(DependencyObject element) where T
return null;
}
+
+ private void QueuedOperationsTimer_Tick(object sender, object e)
+ {
+ _queuedOperationsTimer.Stop();
+ ExecuteQueuedOperations();
+ }
+
+ private void EnqueueOperation(QueuedOperationType queuedOperationType)
+ {
+ EnqueueOperation(new QueuedOperation(queuedOperationType));
+ }
+
+ private void EnqueueOperation(QueuedOperation queuedOperation)
+ {
+ _lstQueuedOperations.Add(queuedOperation);
+ _queuedOperationsTimer.Start();
+ }
+
+ private void ExecuteQueuedOperations()
+ {
+ try
+ {
+ while (_lstQueuedOperations.Count > 0)
+ {
+ QueuedOperation qo = _lstQueuedOperations[0];
+
+ switch (qo.Type)
+ {
+ case QueuedOperationType.DataSourceAdd:
+ DataSourceAddItem();
+ break;
+ case QueuedOperationType.DataSourceInsert:
+ DataSourceInsertItem(qo.IntValue);
+ break;
+ case QueuedOperationType.DataSourceRemove:
+ DataSourceRemoveItem(qo.IntValue);
+ break;
+ case QueuedOperationType.DataSourceRemoveAll:
+ DataSourceRemoveAllItems();
+ break;
+ case QueuedOperationType.DataSourceReplace:
+ DataSourceReplaceItem(qo.IntValue);
+ break;
+ case QueuedOperationType.DataSourceRaiseResetNotification:
+ DataSourceRaiseResetNotification();
+ break;
+ }
+
+ _lstQueuedOperations.RemoveAt(0);
+ }
+ }
+ catch (Exception ex)
+ {
+ txtExceptionReport.Text = ex.ToString();
+ AppendEventMessage(ex.ToString());
+ }
+ }
}
}
diff --git a/src/controls/dev/ItemsView/InteractionTests/ItemsViewTestsWithInputHelper.cs b/src/controls/dev/ItemsView/InteractionTests/ItemsViewTestsWithInputHelper.cs
index bc4b109dfd..c7991f690b 100644
--- a/src/controls/dev/ItemsView/InteractionTests/ItemsViewTestsWithInputHelper.cs
+++ b/src/controls/dev/ItemsView/InteractionTests/ItemsViewTestsWithInputHelper.cs
@@ -401,12 +401,12 @@ public void PanItemsView()
ComboBox cmbItemsSource = new ComboBox(FindElement.ById("cmbItemsSource"));
Verify.IsNotNull(cmbItemsSource, "Verifying that cmbItemsSource was found");
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium StackPanel)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium StackPanel)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium StackPanel)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium StackPanel)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
- Log.Comment("Changing ItemsSource selection to 'List'");
- cmbItemsSource.SelectItemByName("List");
+ Log.Comment("Changing ItemsSource selection to 'List'");
+ cmbItemsSource.SelectItemByName("List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
// Tapping button before attempting pan operation to guarantee effective touch input
@@ -480,6 +480,14 @@ public void KeyboardNavigationInItemsViewWithLinedFlowLayout()
KeyboardNavigationWithLayout(layout: "LinedFlowLayout", useLateralMoves: true);
}
+ [TestMethod]
+ [TestProperty("TestSuite", "A")]
+ [TestProperty("Description", "Exercises the PageDown/PageUp, Home/End, Left/Right/Down/Up keys in an ItemsView with LinedFlowLayout & focusable control inside ItemContainer.")]
+ public void KeyboardNavigationInItemsViewWithLinedFlowLayoutAndInnerFocusableControl()
+ {
+ KeyboardNavigationWithLayout(layout: "LinedFlowLayout", useLateralMoves: true, useFocusableControlInItemContainer: true);
+ }
+
[TestMethod]
[TestProperty("TestSuite", "A")]
[TestProperty("Description", "Exercises the PageDown/PageUp, Home/End, Left/Right/Down/Up keys in an ItemsView with StackLayout.")]
@@ -672,8 +680,8 @@ public void BringFocusedItemIntoView()
Verify.IsNotNull(cmbItemsSourceUIObject, "Verifying that cmbItemsSource was found");
ComboBox itemsSourceComboBox = new ComboBox(cmbItemsSourceUIObject);
- Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
- itemsSourceComboBox.SelectItemByName("ObservableCollection");
+ Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
+ itemsSourceComboBox.SelectItemByName("ObservableCollection");
Log.Comment("Selection is now {0}", itemsSourceComboBox.Selection[0].Name);
Log.Comment("Retrieving & filling txtItemsViewMethodIndex");
@@ -791,12 +799,12 @@ public void ClickedItemBroughtIntoView()
ComboBox cmbItemsSource = new ComboBox(FindElement.ById("cmbItemsSource"));
Verify.IsNotNull(cmbItemsSource, "Verifying that cmbItemsSource was found");
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium ItemContainer)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium ItemContainer)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
- Log.Comment("Changing ItemsSource selection to 'List'");
- cmbItemsSource.SelectItemByName("List");
+ Log.Comment("Changing ItemsSource selection to 'List'");
+ cmbItemsSource.SelectItemByName("List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Retrieving itemsView");
@@ -874,8 +882,8 @@ public void CanDragItemContainerAfterPan()
ComboBox cmbItemsSource = new ComboBox(FindElement.ById("cmbItemsSource"));
Verify.IsNotNull(cmbItemsSource, "Verifying that cmbItemsSource was found");
- Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
- cmbItemsSource.SelectItemByName("ObservableCollection");
+ Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
+ cmbItemsSource.SelectItemByName("ObservableCollection");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Retrieving and selecting first ItemContainer.");
@@ -1147,8 +1155,8 @@ public void UseLinedFlowLayoutWithoutMinWidth()
Verify.IsNotNull(cmbItemsSourceUIObject, "Verifying that cmbItemsSource was found");
ComboBox cmbItemsSource = new ComboBox(cmbItemsSourceUIObject);
- Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
- cmbItemsSource.SelectItemByName("ObservableCollection");
+ Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
+ cmbItemsSource.SelectItemByName("ObservableCollection");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Wait.ForIdle();
@@ -1227,8 +1235,8 @@ public void UseLinedFlowLayoutWithoutLineHeight()
Verify.IsNotNull(cmbItemsSourceUIObject, "Verifying that cmbItemsSource was found");
ComboBox cmbItemsSource = new ComboBox(cmbItemsSourceUIObject);
- Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
- cmbItemsSource.SelectItemByName("ObservableCollection");
+ Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
+ cmbItemsSource.SelectItemByName("ObservableCollection");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Wait.ForIdle();
@@ -1313,12 +1321,12 @@ public void InsertAndRemoveItems()
cmbLayout.SelectItemByName("LinedFlowLayout");
Log.Comment("Selection is now {0}", cmbLayout.Selection[0].Name);
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium ItemContainer)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium ItemContainer)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
- Log.Comment("Changing ItemsSource selection to 'ObservableCollection'");
- cmbItemsSource.SelectItemByName("ObservableCollection");
+ Log.Comment("Changing ItemsSource selection to 'ObservableCollection'");
+ cmbItemsSource.SelectItemByName("ObservableCollection");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Changing txtItemsSourceIndexes text to '0, 0, 0'");
@@ -1414,8 +1422,8 @@ private void StartBringItemIntoView(bool clearItemAspectRatios)
ComboBox cmbItemsSource = new ComboBox(FindElement.ById("cmbItemsSource"));
Verify.IsNotNull(cmbItemsSource, "Verifying that cmbItemsSource was found");
- Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
- cmbItemsSource.SelectItemByName("ObservableCollection");
+ Log.Comment("Changing cmbItemsSource selection to 'ObservableCollection'");
+ cmbItemsSource.SelectItemByName("ObservableCollection");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Setting up ItemsView.StartBringItemIntoView parameters.");
@@ -1877,12 +1885,12 @@ private void TabIntoItemsViewWithoutCurrentItem(bool useShiftTab)
cmbLayout.SelectItemByName("LinedFlowLayout");
Log.Comment("Selection is now {0}", cmbLayout.Selection[0].Name);
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium ItemContainer)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium ItemContainer)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
- Log.Comment("Changing ItemsSource selection to 'List'");
- cmbItemsSource.SelectItemByName("List");
+ Log.Comment("Changing ItemsSource selection to 'List'");
+ cmbItemsSource.SelectItemByName("List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Changing txtScrollViewHorizontalOffset text to '0'");
@@ -2018,8 +2026,8 @@ private void SetUpItemsViewForSelectionTests(string selectionMode, bool provideE
ComboBox cmbItemsSource = new ComboBox(FindElement.ById("cmbItemsSource"));
Verify.IsNotNull(cmbItemsSource, "Verifying that cmbItemsSource was found");
- Log.Comment("Changing cmbItemsSource selection to 'List'");
- cmbItemsSource.SelectItemByName("List");
+ Log.Comment("Changing cmbItemsSource selection to 'List'");
+ cmbItemsSource.SelectItemByName("List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
}
@@ -2041,7 +2049,7 @@ private string GetSelectedItems()
return txtSelectedItems.Value;
}
- private void KeyboardNavigationWithLayout(string layout, bool useLateralMoves)
+ private void KeyboardNavigationWithLayout(string layout, bool useLateralMoves, bool useFocusableControlInItemContainer = false)
{
Log.Comment("Selecting ItemsView interactive tests");
@@ -2063,12 +2071,20 @@ private void KeyboardNavigationWithLayout(string layout, bool useLateralMoves)
cmbLayout.SelectItemByName(layout);
Log.Comment("Selection is now {0}", cmbLayout.Selection[0].Name);
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium ItemContainer)");
+ if (useFocusableControlInItemContainer)
+ {
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (ItemContainer with ToggleButton)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (ItemContainer with ToggleButton)");
+ }
+ else
+ {
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium ItemContainer)");
+ }
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
- Log.Comment("Changing ItemsSource selection to 'List'");
- cmbItemsSource.SelectItemByName("List");
+ Log.Comment("Changing ItemsSource selection to 'List'");
+ cmbItemsSource.SelectItemByName("List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Retrieving itemsView");
@@ -2204,18 +2220,18 @@ private void KeyboardNavigationWithFastKeystrokes(string layout, Key key)
if (layout == "LinedFlowLayout")
{
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Square ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Square ItemContainer)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Square ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Square ItemContainer)");
}
else
{
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium ItemContainer)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium ItemContainer)");
}
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
- Log.Comment("Changing ItemsSource selection to 'Large List'");
- cmbItemsSource.SelectItemByName("Large List");
+ Log.Comment("Changing ItemsSource selection to 'Large List'");
+ cmbItemsSource.SelectItemByName("Large List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
if (layout == "LinedFlowLayout")
@@ -2406,19 +2422,19 @@ private void VerifyItemsViewItemInvokedEvent(bool useItemContainer, bool isItemI
if (useItemContainer)
{
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium ItemContainer)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium ItemContainer)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
}
else
{
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Small ContentControl)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Small ContentControl)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Small ContentControl)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Small ContentControl)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
}
- Log.Comment("Changing ItemsSource selection to 'List'");
- cmbItemsSource.SelectItemByName("List");
+ Log.Comment("Changing ItemsSource selection to 'List'");
+ cmbItemsSource.SelectItemByName("List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Retrieving itemsView");
@@ -2487,19 +2503,19 @@ private void TabNavigationThroughItemsView(bool useItemContainer, string selecti
if (useItemContainer)
{
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Medium ItemContainer)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Medium ItemContainer)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Medium ItemContainer)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Medium ItemContainer)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
}
else
{
- Log.Comment("Changing ItemTemplate selection to 'Recipe DataTemplate (Small ContentControl)'");
- cmbItemTemplate.SelectItemByName("Recipe DataTemplate (Small ContentControl)");
+ Log.Comment("Changing ItemTemplate selection to 'Entity DataTemplate (Small ContentControl)'");
+ cmbItemTemplate.SelectItemByName("Entity DataTemplate (Small ContentControl)");
Log.Comment("Selection is now {0}", cmbItemTemplate.Selection[0].Name);
}
- Log.Comment("Changing ItemsSource selection to 'List'");
- cmbItemsSource.SelectItemByName("List");
+ Log.Comment("Changing ItemsSource selection to 'List'");
+ cmbItemsSource.SelectItemByName("List");
Log.Comment("Selection is now {0}", cmbItemsSource.Selection[0].Name);
Log.Comment("Retrieving itemsView");
diff --git a/src/controls/dev/ItemsView/ItemsView.cpp b/src/controls/dev/ItemsView/ItemsView.cpp
index 524185506d..6a3cf03e44 100644
--- a/src/controls/dev/ItemsView/ItemsView.cpp
+++ b/src/controls/dev/ItemsView/ItemsView.cpp
@@ -1585,6 +1585,9 @@ int ItemsView::GetCornerFocusableItem(
return itemIndex;
}
+// Returns the ItemsRepeater child index for the provided UIElement.
+// All ItemContainer instances in the element parent chain are candidates
+// until a match is found. Returns -1 when no match was made.
int ItemsView::GetElementIndex(
const winrt::UIElement& element) const
{
@@ -1592,7 +1595,29 @@ int ItemsView::GetElementIndex(
if (auto const& itemsRepeater = m_itemsRepeater.get())
{
- return itemsRepeater.GetElementIndex(element);
+ int index = -1;
+ winrt::ItemContainer itemContainer = element.try_as();
+
+ if (itemContainer == nullptr)
+ {
+ itemContainer = SharedHelpers::GetAncestorOfType(element);
+ }
+
+ if (itemContainer != nullptr)
+ {
+ do
+ {
+ index = itemsRepeater.GetElementIndex(itemContainer);
+
+ if (index == -1)
+ {
+ itemContainer = SharedHelpers::GetAncestorOfType(itemContainer);
+ }
+ }
+ while (index == -1 && itemContainer != nullptr);
+ }
+
+ return index;
}
return -1;
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture1.png b/src/controls/dev/ItemsView/TestUI/Images/Picture1.png
new file mode 100644
index 0000000000..9164d09278
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture1.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture10.png b/src/controls/dev/ItemsView/TestUI/Images/Picture10.png
new file mode 100644
index 0000000000..7775630367
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture10.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture11.png b/src/controls/dev/ItemsView/TestUI/Images/Picture11.png
new file mode 100644
index 0000000000..d6a15115ea
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture11.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture12.png b/src/controls/dev/ItemsView/TestUI/Images/Picture12.png
new file mode 100644
index 0000000000..363b5f8ab4
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture12.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture13.png b/src/controls/dev/ItemsView/TestUI/Images/Picture13.png
new file mode 100644
index 0000000000..1d03a38388
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture13.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture14.png b/src/controls/dev/ItemsView/TestUI/Images/Picture14.png
new file mode 100644
index 0000000000..52b8202669
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture14.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture15.png b/src/controls/dev/ItemsView/TestUI/Images/Picture15.png
new file mode 100644
index 0000000000..1accb53262
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture15.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture16.png b/src/controls/dev/ItemsView/TestUI/Images/Picture16.png
new file mode 100644
index 0000000000..199a6cdbeb
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture16.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture17.png b/src/controls/dev/ItemsView/TestUI/Images/Picture17.png
new file mode 100644
index 0000000000..9efbb7cefb
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture17.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture18.png b/src/controls/dev/ItemsView/TestUI/Images/Picture18.png
new file mode 100644
index 0000000000..5f37efed19
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture18.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture19.png b/src/controls/dev/ItemsView/TestUI/Images/Picture19.png
new file mode 100644
index 0000000000..16cf0eaf52
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture19.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture2.png b/src/controls/dev/ItemsView/TestUI/Images/Picture2.png
new file mode 100644
index 0000000000..ac3e3709ba
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture2.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture20.png b/src/controls/dev/ItemsView/TestUI/Images/Picture20.png
new file mode 100644
index 0000000000..7fc3d7f659
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture20.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture21.png b/src/controls/dev/ItemsView/TestUI/Images/Picture21.png
new file mode 100644
index 0000000000..de628d969d
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture21.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture22.png b/src/controls/dev/ItemsView/TestUI/Images/Picture22.png
new file mode 100644
index 0000000000..281e112ddd
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture22.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture23.png b/src/controls/dev/ItemsView/TestUI/Images/Picture23.png
new file mode 100644
index 0000000000..8cd2e781ec
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture23.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture24.png b/src/controls/dev/ItemsView/TestUI/Images/Picture24.png
new file mode 100644
index 0000000000..c45be95098
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture24.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture25.png b/src/controls/dev/ItemsView/TestUI/Images/Picture25.png
new file mode 100644
index 0000000000..9bc548bf1e
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture25.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture26.png b/src/controls/dev/ItemsView/TestUI/Images/Picture26.png
new file mode 100644
index 0000000000..1b94a01afc
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture26.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture27.png b/src/controls/dev/ItemsView/TestUI/Images/Picture27.png
new file mode 100644
index 0000000000..395f0ddbc0
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture27.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture28.png b/src/controls/dev/ItemsView/TestUI/Images/Picture28.png
new file mode 100644
index 0000000000..4b67e22cc4
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture28.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture29.png b/src/controls/dev/ItemsView/TestUI/Images/Picture29.png
new file mode 100644
index 0000000000..c2182ccc24
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture29.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture3.png b/src/controls/dev/ItemsView/TestUI/Images/Picture3.png
new file mode 100644
index 0000000000..278ee6002b
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture3.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture30.png b/src/controls/dev/ItemsView/TestUI/Images/Picture30.png
new file mode 100644
index 0000000000..06c6de6dc2
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture30.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture31.png b/src/controls/dev/ItemsView/TestUI/Images/Picture31.png
new file mode 100644
index 0000000000..cc4b85044e
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture31.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture32.png b/src/controls/dev/ItemsView/TestUI/Images/Picture32.png
new file mode 100644
index 0000000000..cc8284e37e
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture32.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture33.png b/src/controls/dev/ItemsView/TestUI/Images/Picture33.png
new file mode 100644
index 0000000000..7f53983658
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture33.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture34.png b/src/controls/dev/ItemsView/TestUI/Images/Picture34.png
new file mode 100644
index 0000000000..3612a75634
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture34.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture35.png b/src/controls/dev/ItemsView/TestUI/Images/Picture35.png
new file mode 100644
index 0000000000..ac37e65c24
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture35.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture36.png b/src/controls/dev/ItemsView/TestUI/Images/Picture36.png
new file mode 100644
index 0000000000..66f91a6e31
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture36.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture37.png b/src/controls/dev/ItemsView/TestUI/Images/Picture37.png
new file mode 100644
index 0000000000..3d877bce19
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture37.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture38.png b/src/controls/dev/ItemsView/TestUI/Images/Picture38.png
new file mode 100644
index 0000000000..523525932d
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture38.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture39.png b/src/controls/dev/ItemsView/TestUI/Images/Picture39.png
new file mode 100644
index 0000000000..ec44894eb1
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture39.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture4.png b/src/controls/dev/ItemsView/TestUI/Images/Picture4.png
new file mode 100644
index 0000000000..2034ad3af1
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture4.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture40.png b/src/controls/dev/ItemsView/TestUI/Images/Picture40.png
new file mode 100644
index 0000000000..583fe87bb6
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture40.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture5.png b/src/controls/dev/ItemsView/TestUI/Images/Picture5.png
new file mode 100644
index 0000000000..31eb66d9d6
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture5.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture6.png b/src/controls/dev/ItemsView/TestUI/Images/Picture6.png
new file mode 100644
index 0000000000..5faf82da17
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture6.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture7.png b/src/controls/dev/ItemsView/TestUI/Images/Picture7.png
new file mode 100644
index 0000000000..839055e379
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture7.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture8.png b/src/controls/dev/ItemsView/TestUI/Images/Picture8.png
new file mode 100644
index 0000000000..43278e06b9
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture8.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/Images/Picture9.png b/src/controls/dev/ItemsView/TestUI/Images/Picture9.png
new file mode 100644
index 0000000000..762462cbf1
Binary files /dev/null and b/src/controls/dev/ItemsView/TestUI/Images/Picture9.png differ
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml b/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml
index d1680c3d47..9947ffdd06 100644
--- a/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml
@@ -10,7 +10,7 @@
mc:Ignorable="d">
-
+
@@ -20,7 +20,7 @@
-
+
@@ -30,7 +30,7 @@
-
+
@@ -43,7 +43,7 @@
-
+
@@ -56,7 +56,7 @@
-
+
@@ -69,7 +69,7 @@
-
+
@@ -78,14 +78,14 @@
-
+
-
+
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml.cs b/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml.cs
index 9bd4523d15..0e53f1b78e 100644
--- a/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml.cs
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewIntegrationPage.xaml.cs
@@ -34,7 +34,7 @@ public sealed partial class ItemsViewIntegrationPage : TestPage
private object _asyncEventReportingLock = new object();
private List _lstAsyncEventMessage = new List();
private List _fullLogs = new List();
- private ObservableCollection _colPhotos = null;
+ private ObservableCollection _colPhotos = null;
private DataTemplate[] _photoTemplates = new DataTemplate[8];
private SolidColorBrush _redBrush = new SolidColorBrush(Colors.Red);
private SolidColorBrush _whiteBrush = new SolidColorBrush(Colors.White);
@@ -349,8 +349,8 @@ private void PopulateHeader()
{
if (chkGeneralInfoLogs.IsChecked == true)
{
- Recipe firstRelevantPhoto = _colPhotos[firstRelevantItemContainerIndex];
- Recipe lastRelevantPhoto = _colPhotos[lastRelevantItemContainerIndex];
+ Entity firstRelevantPhoto = _colPhotos[firstRelevantItemContainerIndex];
+ Entity lastRelevantPhoto = _colPhotos[lastRelevantItemContainerIndex];
AppendAsyncEventMessage($"PopulateHeader firstRelevantPhoto={firstRelevantPhoto.Description}, lastRelevantPhoto={lastRelevantPhoto.Description}");
}
@@ -419,7 +419,7 @@ private void PopulatePhotosCollection()
UnhookPhotosCollectionChanged();
}
- _colPhotos = new ObservableCollection();
+ _colPhotos = new ObservableCollection();
var rnd = chkUseConstantMonthCount.IsChecked == true ? null : new Random();
DateTime today = DateTime.Now.Date;
@@ -452,7 +452,7 @@ private void PopulatePhotosCollection()
for (int photoIndex = 0; photoIndex < monthCount; photoIndex++)
{
- _colPhotos.Add(new Recipe()
+ _colPhotos.Add(new Entity()
{
ImageUri = new Uri(string.Format("ms-appx:///Images/vette{0}.jpg", chkUseConstantMonthCount.IsChecked == true ? (yearIndex * 50 + monthIndex * 5 + photoIndex) % 126 + 1 : rnd.Next(1, 127))),
Description = GetMonthNameFromIndex(monthIndex) + " " + year + " - #" + photoIndex
@@ -1343,7 +1343,7 @@ private void BtnAddItemsSourceItem_Click(object sender, RoutedEventArgs args)
_monthPhotoCounts = new int[_yearCount, 12];
if (_colPhotos == null)
{
- _colPhotos = new ObservableCollection();
+ _colPhotos = new ObservableCollection();
HookPhotosCollectionChanged();
}
@@ -1400,7 +1400,7 @@ private void BtnAddItemsSourceItem_Click(object sender, RoutedEventArgs args)
Random rnd = new Random();
- _colPhotos.Add(new Recipe()
+ _colPhotos.Add(new Entity()
{
ImageUri = new Uri(string.Format("ms-appx:///Images/vette{0}.jpg", rnd.Next(1, 127))),
Description = GetMonthNameFromIndex(monthIndex) + " " + year + " - #" + photoIndex
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml b/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml
index 0b17d53722..7bcfc73ee8 100644
--- a/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml
@@ -10,7 +10,7 @@
mc:Ignorable="d">
-
+
@@ -19,21 +19,21 @@
-
+
-
+
-
+
@@ -42,7 +42,7 @@
-
+
@@ -51,6 +51,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -95,20 +109,21 @@
null
- Recipe DataTemplate (Small ContentControl)
- Recipe DataTemplate (Medium StackPanel)
- Recipe DataTemplate (Large StackPanel)
- Recipe DataTemplate (Medium ItemContainer)
- Recipe DataTemplate (Square ItemContainer)
+ Entity DataTemplate (Small ContentControl)
+ Entity DataTemplate (Medium StackPanel)
+ Entity DataTemplate (Large StackPanel)
+ Entity DataTemplate (Medium ItemContainer)
+ Entity DataTemplate (Square ItemContainer)
+ Entity DataTemplate (ItemContainer with ToggleButton)
null
- List<Recipe>
- Large List<Recipe>
- ObservableCollection<Recipe>
+ List<Entity>
+ Large List<Entity>
+ ObservableCollection<Entity>
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml.cs b/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml.cs
index ba8e5dc7ee..1407137c21 100644
--- a/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml.cs
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewInteractiveTestsPage.xaml.cs
@@ -22,10 +22,10 @@ public sealed partial class ItemsViewInteractiveTestsPage : TestPage
private int _scrollViewResetCorrelationId = -1;
private int _scrollViewOffsetChangeCorrelationId = -1;
private int _scrollViewZoomFactorChangeCorrelationId = -1;
- private ObservableCollection _colRecipes = null;
- private List _lstRecipes = null;
- private List _lstLargeRecipes = null;
- private DataTemplate[] _recipeTemplates = new DataTemplate[5];
+ private ObservableCollection _colEntities = null;
+ private List _lstEntities = null;
+ private List _lstLargeEntities = null;
+ private DataTemplate[] _entityTemplates = new DataTemplate[6];
private LinedFlowLayout _linedFlowLayout = null;
private StackLayout _stackLayout = null;
private UniformGridLayout _uniformGridLayout = null;
@@ -208,12 +208,12 @@ private void CmbItemTemplate_SelectionChanged(object sender, SelectionChangedEve
{
int templateIndex = cmbItemTemplate.SelectedIndex - 1;
- if (_recipeTemplates[templateIndex] == null)
+ if (_entityTemplates[templateIndex] == null)
{
- _recipeTemplates[templateIndex] = Resources["recipeTemplate" + cmbItemTemplate.SelectedIndex.ToString()] as DataTemplate;
+ _entityTemplates[templateIndex] = Resources["entityTemplate" + cmbItemTemplate.SelectedIndex.ToString()] as DataTemplate;
}
- itemsView.ItemTemplate = _recipeTemplates[templateIndex];
+ itemsView.ItemTemplate = _entityTemplates[templateIndex];
}
UpdateLinedFlowLayoutLineHeight();
@@ -238,43 +238,43 @@ private void CmbItemsSource_SelectionChanged(object sender, SelectionChangedEven
itemsView.ItemsSource = null;
break;
case 1:
- if (_lstRecipes == null)
+ if (_lstEntities == null)
{
- _lstRecipes = new List(
+ _lstEntities = new List(
Enumerable.Range(0, 50).Select(k =>
- new Recipe
+ new Entity
{
ImageUri = new Uri(string.Format("ms-appx:///Images/recipe{0}.png", k % 8 + 1)),
Description = k + " - " + _lorem.Substring(0, k)
}));
}
- itemsView.ItemsSource = _lstRecipes;
+ itemsView.ItemsSource = _lstEntities;
break;
case 2:
- if (_lstLargeRecipes == null)
+ if (_lstLargeEntities == null)
{
- _lstLargeRecipes = new List(
+ _lstLargeEntities = new List(
Enumerable.Range(0, 1000).Select(k =>
- new Recipe
+ new Entity
{
ImageUri = new Uri(string.Format("ms-appx:///Images/recipe{0}.png", k % 8 + 1)),
Description = k + " - " + _lorem.Substring(0, k % 50 + 1)
}));
}
- itemsView.ItemsSource = _lstLargeRecipes;
+ itemsView.ItemsSource = _lstLargeEntities;
break;
case 3:
- if (_colRecipes == null)
+ if (_colEntities == null)
{
- _colRecipes = new ObservableCollection(
+ _colEntities = new ObservableCollection(
Enumerable.Range(0, 25).Select(k =>
- new Recipe
+ new Entity
{
ImageUri = new Uri(string.Format("ms-appx:///Images/recipe{0}.png", k % 8 + 1)),
Description = k + " - " + _lorem.Substring(0, 2 * k)
}));
}
- itemsView.ItemsSource = _colRecipes;
+ itemsView.ItemsSource = _colEntities;
break;
}
}
@@ -373,7 +373,7 @@ private void LinedFlowLayout_ItemsInfoRequested(LinedFlowLayout sender, LinedFlo
args.MinWidth = 80.0;
- double[] desiredAspectRatios = new double[chkUseFastPath.IsChecked == true ? (itemsView.ItemsSource as IReadOnlyCollection).Count : args.ItemsRangeRequestedLength];
+ double[] desiredAspectRatios = new double[chkUseFastPath.IsChecked == true ? (itemsView.ItemsSource as IReadOnlyCollection).Count : args.ItemsRangeRequestedLength];
if (chkUseFastPath.IsChecked == true)
{
@@ -579,42 +579,42 @@ private void InsertItem(int index)
switch (cmbItemsSource.SelectedIndex)
{
case 1:
- if (_lstRecipes != null)
+ if (_lstEntities != null)
{
- int rank = _lstRecipes.Count;
- Recipe recipe = new Recipe
+ int rank = _lstEntities.Count;
+ Entity entity = new Entity
{
ImageUri = new Uri(string.Format("ms-appx:///Images/recipe{0}.png", rank % 8 + 1)),
Description = rank + " - " + _lorem.Substring(0, rank)
};
- _lstRecipes.Insert(index, recipe);
+ _lstEntities.Insert(index, entity);
}
break;
case 2:
- if (_lstLargeRecipes != null)
+ if (_lstLargeEntities != null)
{
- int rank = _lstLargeRecipes.Count;
- Recipe recipe = new Recipe
+ int rank = _lstLargeEntities.Count;
+ Entity entity = new Entity
{
ImageUri = new Uri(string.Format("ms-appx:///Images/recipe{0}.png", rank % 8 + 1)),
Description = rank + " - " + _lorem.Substring(0, rank % 50 + 1)
};
- _lstLargeRecipes.Insert(index, recipe);
+ _lstLargeEntities.Insert(index, entity);
}
break;
case 3:
- if (_colRecipes != null)
+ if (_colEntities != null)
{
- int rank = _colRecipes.Count;
- Recipe recipe = new Recipe
+ int rank = _colEntities.Count;
+ Entity entity = new Entity
{
ImageUri = new Uri(string.Format("ms-appx:///Images/recipe{0}.png", rank % 8 + 1)),
Description = rank + " - " + _lorem.Substring(0, 2 * rank)
};
- _colRecipes.Insert(index, recipe);
+ _colEntities.Insert(index, entity);
}
break;
}
@@ -635,21 +635,21 @@ private void RemoveItem(int index)
switch (cmbItemsSource.SelectedIndex)
{
case 1:
- if (_lstRecipes != null)
+ if (_lstEntities != null)
{
- _lstRecipes.RemoveAt(index);
+ _lstEntities.RemoveAt(index);
}
break;
case 2:
- if (_lstLargeRecipes != null)
+ if (_lstLargeEntities != null)
{
- _lstLargeRecipes.RemoveAt(index);
+ _lstLargeEntities.RemoveAt(index);
}
break;
case 3:
- if (_colRecipes != null)
+ if (_colEntities != null)
{
- _colRecipes.RemoveAt(index);
+ _colEntities.RemoveAt(index);
}
break;
}
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml b/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml
index f4dd201ec6..647723cfb8 100644
--- a/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml
@@ -39,5 +39,6 @@
+
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml.cs b/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml.cs
index 9509ee1f60..3732cd8151 100644
--- a/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml.cs
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewPage.xaml.cs
@@ -25,6 +25,7 @@ public ItemsViewPage()
navigateToIntegration.Click += delegate { Frame.NavigateWithoutAnimation(typeof(ItemsViewIntegrationPage), 0); };
navigateToBlank.Click += delegate { Frame.NavigateWithoutAnimation(typeof(ItemsViewBlankPage), 0); };
navigateToTransitionProvider.Click += delegate { Frame.NavigateWithoutAnimation(typeof(ItemsViewTransitionPage), 0); };
+ navigateToPictureLibrary.Click += delegate { Frame.NavigateWithoutAnimation(typeof(ItemsViewPictureLibraryPage), 0); };
}
private void CmbItemsViewOutputDebugStringLevel_SelectionChanged(object sender, SelectionChangedEventArgs e)
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewPictureLibraryPage.xaml b/src/controls/dev/ItemsView/TestUI/ItemsViewPictureLibraryPage.xaml
new file mode 100644
index 0000000000..a15acc3b00
--- /dev/null
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewPictureLibraryPage.xaml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/controls/dev/ItemsView/TestUI/ItemsViewPictureLibraryPage.xaml.cs b/src/controls/dev/ItemsView/TestUI/ItemsViewPictureLibraryPage.xaml.cs
new file mode 100644
index 0000000000..c73c6c4d67
--- /dev/null
+++ b/src/controls/dev/ItemsView/TestUI/ItemsViewPictureLibraryPage.xaml.cs
@@ -0,0 +1,595 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Private.Controls;
+
+namespace MUXControlsTestApp
+{
+ public sealed partial class ItemsViewPictureLibraryPage : TestPage
+ {
+ private List lstEventMessage = new List();
+ private PictureLibrary pictureLibrary = null;
+ private double[] aspectRatios = null;
+
+ public ItemsViewPictureLibraryPage()
+ {
+ this.InitializeComponent();
+
+ if (chkLogItemsViewMessages.IsChecked == true || chkLogScrollViewMessages.IsChecked == true || chkLogItemsRepeaterMessages.IsChecked == true)
+ {
+ MUXControlsTestHooks.LoggingMessage += MUXControlsTestHooks_LoggingMessage;
+
+ if (chkLogItemsRepeaterMessages.IsChecked == true)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ItemsRepeater", isLoggingInfoLevel: true, isLoggingVerboseLevel: true);
+ }
+ if (chkLogScrollViewMessages.IsChecked == true)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ScrollView", isLoggingInfoLevel: true, isLoggingVerboseLevel: true);
+ }
+ if (chkLogItemsViewMessages.IsChecked == true)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ItemsView", isLoggingInfoLevel: true, isLoggingVerboseLevel: true);
+ }
+ }
+
+ pictureLibrary = PictureLibrary.CreateLarge();
+ }
+
+ private void ChkCustomUI_Checked(object sender, RoutedEventArgs e)
+ {
+ if (grdCustomUI != null)
+ grdCustomUI.Visibility = Visibility.Visible;
+ }
+
+ private void ChkCustomUI_Unchecked(object sender, RoutedEventArgs e)
+ {
+ if (grdCustomUI != null)
+ grdCustomUI.Visibility = Visibility.Collapsed;
+ }
+
+ private void ChkLogs_Checked(object sender, RoutedEventArgs e)
+ {
+ if (grdLogs != null)
+ grdLogs.Visibility = Visibility.Visible;
+ }
+
+ private void ChkLogs_Unchecked(object sender, RoutedEventArgs e)
+ {
+ if (grdLogs != null)
+ grdLogs.Visibility = Visibility.Collapsed;
+ }
+
+ private void ItemsView_Loaded(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage($"ItemsView.Loaded");
+ if (chkLogItemsRepeaterEvents.IsChecked == true)
+ {
+ LogItemsRepeaterInfo();
+ }
+ if (chkLogScrollViewEvents.IsChecked == true)
+ {
+ LogScrollViewInfo();
+ }
+ LogItemsViewInfo();
+ }
+
+ private void ItemsView_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ AppendEventMessage($"ItemsView.SizeChanged Size={itemsView.ActualWidth}, {itemsView.ActualHeight}");
+ if (chkLogItemsRepeaterEvents.IsChecked == true)
+ {
+ LogItemsRepeaterInfo();
+ }
+ if (chkLogScrollViewEvents.IsChecked == true)
+ {
+ LogScrollViewInfo();
+ }
+ LogItemsViewInfo();
+ }
+
+ private void ItemsView_GettingFocus(UIElement sender, Microsoft.UI.Xaml.Input.GettingFocusEventArgs args)
+ {
+ FrameworkElement oldFE = args.OldFocusedElement as FrameworkElement;
+ string oldFEName = (oldFE == null) ? "null" : oldFE.Name;
+ FrameworkElement newFE = args.NewFocusedElement as FrameworkElement;
+ string newFEName = (newFE == null) ? "null" : newFE.Name;
+
+ AppendEventMessage($"ItemsView.GettingFocus FocusState={args.FocusState}, Direction={args.Direction}, InputDevice={args.InputDevice}, oldFE={oldFEName}, newFE={newFEName}");
+ }
+
+ private void ItemsView_LostFocus(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage("ItemsView.LostFocus");
+ }
+
+ private void ItemsView_LosingFocus(UIElement sender, Microsoft.UI.Xaml.Input.LosingFocusEventArgs args)
+ {
+ FrameworkElement oldFE = args.OldFocusedElement as FrameworkElement;
+ string oldFEName = (oldFE == null) ? "null" : oldFE.Name;
+ FrameworkElement newFE = args.NewFocusedElement as FrameworkElement;
+ string newFEName = (newFE == null) ? "null" : newFE.Name;
+
+ AppendEventMessage($"ItemsView.LosingFocus FocusState={args.FocusState}, Direction={args.Direction}, InputDevice={args.InputDevice}, oldFE={oldFEName}, newFE={newFEName}");
+ }
+
+ private void ItemsView_GotFocus(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage("ItemsView.GotFocus");
+ }
+
+ private void ItemsRepeater_Loaded(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage($"ItemsRepeater.Loaded");
+ LogItemsRepeaterInfo();
+ if (chkLogItemsViewEvents.IsChecked == true)
+ {
+ LogItemsViewInfo();
+ }
+ }
+
+ private void ItemsRepeater_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ AppendEventMessage($"ItemsRepeater.SizeChanged Size={itemsView.ActualWidth}, {itemsView.ActualHeight}");
+ LogItemsRepeaterInfo();
+ if (chkLogItemsViewEvents.IsChecked == true)
+ {
+ LogItemsViewInfo();
+ }
+ }
+
+ private void LinedFlowLayout_ItemsInfoRequested(LinedFlowLayout sender, LinedFlowLayoutItemsInfoRequestedEventArgs args)
+ {
+ AppendEventMessage($"LinedFlowLayout.ItemsInfoRequested ItemsRangeStartIndex={args.ItemsRangeStartIndex}, ItemsRangeRequestedLength={args.ItemsRangeRequestedLength}");
+
+ int itemsRangeStartIndex = args.ItemsRangeStartIndex;
+
+ args.SetDesiredAspectRatios(GetAspectRatios(ref itemsRangeStartIndex, args.ItemsRangeRequestedLength));
+ args.ItemsRangeStartIndex = itemsRangeStartIndex;
+ args.MinWidth = 86;
+ }
+
+ private void ScrollView_Loaded(object sender, RoutedEventArgs e)
+ {
+ AppendEventMessage($"ScrollView.Loaded");
+ LogScrollViewInfo();
+ if (chkLogItemsViewEvents.IsChecked == true)
+ {
+ LogItemsViewInfo();
+ }
+ }
+
+ private void ScrollView_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ AppendEventMessage($"ScrollView.SizeChanged Size={itemsView.ActualWidth}, {itemsView.ActualHeight}");
+ LogScrollViewInfo();
+ if (chkLogItemsViewEvents.IsChecked == true)
+ {
+ LogItemsViewInfo();
+ }
+ }
+
+ private void ScrollView_ExtentChanged(ScrollView sender, object args)
+ {
+ AppendEventMessage("ScrollView.ExtentChanged ExtentWidth={sender.ExtentWidth}, ExtentHeight={sender.ExtentHeight}");
+ }
+
+ private void ScrollView_StateChanged(ScrollView sender, object args)
+ {
+ AppendEventMessage($"ScrollView.StateChanged {sender.State.ToString()}");
+ }
+
+ private void ScrollView_ViewChanged(ScrollView sender, object args)
+ {
+ AppendEventMessage($"ScrollView.ViewChanged HorizontalOffset={sender.HorizontalOffset.ToString()}, VerticalOffset={sender.VerticalOffset}, ZoomFactor={sender.ZoomFactor}");
+ }
+
+ private void ScrollView_ScrollAnimationStarting(ScrollView sender, ScrollingScrollAnimationStartingEventArgs args)
+ {
+ AppendEventMessage($"ScrollView.ScrollAnimationStarting OffsetsChangeCorrelationId={args.CorrelationId}, SP=({args.StartPosition.X}, {args.StartPosition.Y}), EP=({args.EndPosition.X}, {args.EndPosition.Y})");
+ }
+
+ private void ScrollView_ZoomAnimationStarting(ScrollView sender, ScrollingZoomAnimationStartingEventArgs args)
+ {
+ AppendEventMessage($"ScrollView.ZoomAnimationStarting ZoomFactorChangeCorrelationId={args.CorrelationId}, CenterPoint={args.CenterPoint}, SZF={args.StartZoomFactor}, EZF={args.EndZoomFactor}");
+ }
+
+ private void ScrollView_ScrollCompleted(ScrollView sender, ScrollingScrollCompletedEventArgs args)
+ {
+ AppendEventMessage($"ScrollView.ScrollCompleted OffsetsChangeCorrelationId={args.CorrelationId}");
+ }
+
+ private void ScrollView_ZoomCompleted(ScrollView sender, ScrollingZoomCompletedEventArgs args)
+ {
+ AppendEventMessage($"ScrollView.ZoomCompleted ZoomFactorChangeCorrelationId={args.CorrelationId}");
+ }
+
+ private void LogItemsRepeaterInfo()
+ {
+ ItemsRepeater itemsRepeater = ItemsViewTestHooks.GetItemsRepeaterPart(itemsView);
+
+ AppendEventMessage($"ItemsRepeater Info: ItemsSource={itemsRepeater.ItemsSource}, ItemTemplate={itemsRepeater.ItemTemplate}, Layout={itemsRepeater.Layout}");
+ }
+
+ private void LogScrollViewInfo()
+ {
+ ScrollView scrollView = ItemsViewTestHooks.GetScrollViewPart(itemsView);
+
+ AppendEventMessage($"ScrollView Info: HorizontalOffset={scrollView.HorizontalOffset}, VerticalOffset={scrollView.VerticalOffset}, ZoomFactor={scrollView.ZoomFactor}");
+ AppendEventMessage($"ScrollView Info: ViewportWidth={scrollView.ViewportWidth}, ExtentHeight={scrollView.ViewportHeight}");
+ AppendEventMessage($"ScrollView Info: ExtentWidth={scrollView.ExtentWidth}, ExtentHeight={scrollView.ExtentHeight}");
+ AppendEventMessage($"ScrollView Info: ScrollableWidth={scrollView.ScrollableWidth}, ScrollableHeight={scrollView.ScrollableHeight}");
+ }
+
+ private void LogItemsViewInfo()
+ {
+ //AppendEventMessage($"ItemsView Info: ItemsSource={itemsView.ItemsSource}, ItemTemplate={itemsView.ItemTemplate}, Layout={itemsView.Layout}");
+ }
+
+ private void BtnClearLogs_Click(object sender, RoutedEventArgs e)
+ {
+ lstLogs.Items.Clear();
+ }
+
+ private void ChkLogItemsRepeaterEvents_Checked(object sender, RoutedEventArgs e)
+ {
+ if (itemsView != null)
+ {
+ ItemsRepeater itemsRepeater = ItemsViewTestHooks.GetItemsRepeaterPart(itemsView);
+
+ if (itemsRepeater != null)
+ {
+ itemsRepeater.Loaded += ItemsRepeater_Loaded;
+ itemsRepeater.SizeChanged += ItemsRepeater_SizeChanged;
+ }
+ }
+ }
+
+ private void ChkLogItemsRepeaterEvents_Unchecked(object sender, RoutedEventArgs e)
+ {
+ if (itemsView != null)
+ {
+ ItemsRepeater itemsRepeater = ItemsViewTestHooks.GetItemsRepeaterPart(itemsView);
+
+ if (itemsRepeater != null)
+ {
+ itemsRepeater.Loaded -= ItemsRepeater_Loaded;
+ itemsRepeater.SizeChanged -= ItemsRepeater_SizeChanged;
+ }
+ }
+ }
+
+ private void ChkLogScrollViewEvents_Checked(object sender, RoutedEventArgs e)
+ {
+ if (itemsView != null)
+ {
+ ScrollView scrollView = ItemsViewTestHooks.GetScrollViewPart(itemsView);
+
+ if (scrollView != null)
+ {
+ scrollView.Loaded += ScrollView_Loaded;
+ scrollView.SizeChanged += ScrollView_SizeChanged;
+ scrollView.ExtentChanged += ScrollView_ExtentChanged;
+ scrollView.StateChanged += ScrollView_StateChanged;
+ scrollView.ViewChanged += ScrollView_ViewChanged;
+ scrollView.ScrollAnimationStarting += ScrollView_ScrollAnimationStarting;
+ scrollView.ZoomAnimationStarting += ScrollView_ZoomAnimationStarting;
+ scrollView.ScrollCompleted += ScrollView_ScrollCompleted;
+ scrollView.ZoomCompleted += ScrollView_ZoomCompleted;
+ }
+ }
+ }
+
+ private void ChkLogScrollViewEvents_Unchecked(object sender, RoutedEventArgs e)
+ {
+ if (itemsView != null)
+ {
+ ScrollView scrollView = ItemsViewTestHooks.GetScrollViewPart(itemsView);
+
+ if (scrollView != null)
+ {
+ scrollView.Loaded -= ScrollView_Loaded;
+ scrollView.SizeChanged -= ScrollView_SizeChanged;
+ scrollView.ExtentChanged -= ScrollView_ExtentChanged;
+ scrollView.StateChanged -= ScrollView_StateChanged;
+ scrollView.ViewChanged -= ScrollView_ViewChanged;
+ scrollView.ScrollAnimationStarting -= ScrollView_ScrollAnimationStarting;
+ scrollView.ZoomAnimationStarting -= ScrollView_ZoomAnimationStarting;
+ scrollView.ScrollCompleted -= ScrollView_ScrollCompleted;
+ scrollView.ZoomCompleted -= ScrollView_ZoomCompleted;
+ }
+ }
+ }
+
+ private void ChkLogItemsViewEvents_Checked(object sender, RoutedEventArgs e)
+ {
+ if (itemsView != null)
+ {
+ itemsView.GettingFocus += ItemsView_GettingFocus;
+ itemsView.GotFocus += ItemsView_GotFocus;
+ itemsView.LosingFocus += ItemsView_LosingFocus;
+ itemsView.LostFocus += ItemsView_LostFocus;
+ itemsView.Loaded += ItemsView_Loaded;
+ itemsView.SizeChanged += ItemsView_SizeChanged;
+ }
+ }
+
+ private void ChkLogItemsViewEvents_Unchecked(object sender, RoutedEventArgs e)
+ {
+ if (itemsView != null)
+ {
+ itemsView.GettingFocus -= ItemsView_GettingFocus;
+ itemsView.GotFocus -= ItemsView_GotFocus;
+ itemsView.LosingFocus -= ItemsView_LosingFocus;
+ itemsView.LostFocus -= ItemsView_LostFocus;
+ itemsView.Loaded -= ItemsView_Loaded;
+ itemsView.SizeChanged -= ItemsView_SizeChanged;
+ }
+ }
+
+ private void ChkLogItemsRepeaterMessages_Checked(object sender, RoutedEventArgs e)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ItemsRepeater", isLoggingInfoLevel: true, isLoggingVerboseLevel: true);
+ if (chkLogItemsViewMessages.IsChecked == false && chkLogScrollViewMessages.IsChecked == false)
+ MUXControlsTestHooks.LoggingMessage += MUXControlsTestHooks_LoggingMessage;
+ }
+
+ private void ChkLogItemsRepeaterMessages_Unchecked(object sender, RoutedEventArgs e)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ItemsRepeater", isLoggingInfoLevel: false, isLoggingVerboseLevel: false);
+ if (chkLogItemsViewMessages.IsChecked == false && chkLogScrollViewMessages.IsChecked == false)
+ MUXControlsTestHooks.LoggingMessage -= MUXControlsTestHooks_LoggingMessage;
+ }
+
+ private void ChkLogScrollViewMessages_Checked(object sender, RoutedEventArgs e)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ScrollView", isLoggingInfoLevel: true, isLoggingVerboseLevel: true);
+ if (chkLogItemsViewMessages.IsChecked == false && chkLogItemsRepeaterMessages.IsChecked == false)
+ MUXControlsTestHooks.LoggingMessage += MUXControlsTestHooks_LoggingMessage;
+ }
+
+ private void ChkLogScrollViewMessages_Unchecked(object sender, RoutedEventArgs e)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ScrollView", isLoggingInfoLevel: false, isLoggingVerboseLevel: false);
+ if (chkLogItemsViewMessages.IsChecked == false && chkLogItemsRepeaterMessages.IsChecked == false)
+ MUXControlsTestHooks.LoggingMessage -= MUXControlsTestHooks_LoggingMessage;
+ }
+
+ private void ChkLogItemsViewMessages_Checked(object sender, RoutedEventArgs e)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ItemsView", isLoggingInfoLevel: true, isLoggingVerboseLevel: true);
+ if (chkLogScrollViewMessages.IsChecked == false && chkLogItemsRepeaterMessages.IsChecked == false)
+ MUXControlsTestHooks.LoggingMessage += MUXControlsTestHooks_LoggingMessage;
+ }
+
+ private void ChkLogItemsViewMessages_Unchecked(object sender, RoutedEventArgs e)
+ {
+ MUXControlsTestHooks.SetLoggingLevelForType("ItemsView", isLoggingInfoLevel: false, isLoggingVerboseLevel: false);
+ if (chkLogScrollViewMessages.IsChecked == false && chkLogItemsRepeaterMessages.IsChecked == false)
+ MUXControlsTestHooks.LoggingMessage -= MUXControlsTestHooks_LoggingMessage;
+ }
+
+ private void MUXControlsTestHooks_LoggingMessage(object sender, MUXControlsTestHooksLoggingMessageEventArgs args)
+ {
+ // Cut off the terminating new line.
+ string msg = args.Message.Substring(0, args.Message.Length - 1);
+ string eventMessage = string.Empty;
+ string senderName = string.Empty;
+
+ try
+ {
+ FrameworkElement fe = sender as FrameworkElement;
+
+ if (fe != null)
+ {
+ senderName = "s:" + fe.Name + ", ";
+ }
+ }
+ catch
+ {
+ }
+
+ if (args.IsVerboseLevel)
+ {
+ eventMessage = "Verbose: " + senderName + "m:" + msg;
+ }
+ else
+ {
+ eventMessage = "Info: " + senderName + "m:" + msg;
+ }
+
+ AppendEventMessage(eventMessage);
+ }
+
+ private double[] GetAspectRatios(ref int itemsRangeStartIndex, int itemsRangeRequestedLength)
+ {
+ const int bufferedAspectRatiosLength = 500;
+ int cappedBufferedAspectRatiosLength = Math.Min(bufferedAspectRatiosLength, pictureLibrary.Count);
+
+ cappedBufferedAspectRatiosLength = Math.Max(cappedBufferedAspectRatiosLength, itemsRangeRequestedLength);
+
+ if (aspectRatios == null || aspectRatios.Length != cappedBufferedAspectRatiosLength)
+ {
+ aspectRatios = new double[cappedBufferedAspectRatiosLength];
+ }
+
+ if (itemsRangeStartIndex > 0 && itemsRangeRequestedLength < cappedBufferedAspectRatiosLength)
+ {
+ itemsRangeStartIndex -= (cappedBufferedAspectRatiosLength - itemsRangeRequestedLength) / 2;
+ }
+
+ if (itemsRangeStartIndex + cappedBufferedAspectRatiosLength - 1 >= pictureLibrary.Count)
+ {
+ cappedBufferedAspectRatiosLength -= itemsRangeStartIndex + cappedBufferedAspectRatiosLength - pictureLibrary.Count;
+ }
+
+ for (int i = 0; i < cappedBufferedAspectRatiosLength; i++)
+ {
+ aspectRatios[i] = pictureLibrary[itemsRangeStartIndex + i].AspectRatio;
+ }
+
+ AppendEventMessage($"GetAspectRatios: itemsRangeStartIndex={itemsRangeStartIndex}, cappedBufferedAspectRatiosLength={cappedBufferedAspectRatiosLength}");
+
+ return aspectRatios;
+ }
+
+ private void AppendEventMessage(string eventMessage)
+ {
+ while (eventMessage.Length > 0)
+ {
+ string msgHead = eventMessage;
+
+ if (eventMessage.Length > 110)
+ {
+ int commaIndex = eventMessage.IndexOf(',', 110);
+ if (commaIndex != -1)
+ {
+ msgHead = eventMessage.Substring(0, commaIndex);
+ eventMessage = eventMessage.Substring(commaIndex + 1);
+ }
+ else
+ {
+ eventMessage = string.Empty;
+ }
+ }
+ else
+ {
+ eventMessage = string.Empty;
+ }
+
+ lstEventMessage.Add(msgHead);
+ }
+ AppendEventMessage();
+ }
+
+ private void AppendEventMessage()
+ {
+ foreach (string eventMessage in lstEventMessage)
+ {
+ lstLogs.Items.Add(eventMessage);
+ }
+ lstEventMessage.Clear();
+ }
+
+ private void BtnClearExceptionReport_Click(object sender, RoutedEventArgs e)
+ {
+ txtExceptionReport.Text = string.Empty;
+ }
+ }
+
+ public class Picture
+ {
+ public string Path { get; set; }
+ public string Title { get; set; } = string.Empty;
+ public int Id { get; set; }
+
+ public double AspectRatio { get; set; } = 1;
+
+ public Location Location { get; set; }
+ }
+
+ public enum Location
+ {
+ Seattle,
+ Miami,
+ LA
+ }
+
+ public class PictureLibrary : ObservableCollection
"));
var elementFactory = (RecyclingElementFactory)root.Resources["ElementFactory"];
scroller = (ScrollViewer)root.FindName("Scroller");
- repeater = (ItemsRepeater)root.FindName("ItemsRepeater");
+ itemsRepeater = (ItemsRepeater)root.FindName("ItemsRepeater");
var items = Enumerable.Range(0, 400).Select(i => string.Format("{0}: {1}", i, lorem.Substring(0, 250)));
- repeater.ItemsSource = items;
+ itemsRepeater.ItemsSource = items;
scroller.ViewChanged += (o, e) =>
{
- Log.Comment("ViewChanged: " + scroller.VerticalOffset);
+ Log.Comment($"ScrollViewer.ViewChanged - VerticalOffset: {scroller.VerticalOffset}");
viewChangedOffsets.Add(scroller.VerticalOffset);
- if(!e.IsIntermediate)
+ if (!e.IsIntermediate)
{
viewChangeCompletedEvent.Set();
}
};
- scroller.EffectiveViewportChanged += (o, args) =>
- {
- effectiveViewChangeCompletedEvent.Set();
- };
-
Content = root;
root.Loaded += delegate
@@ -441,70 +434,90 @@ public void CanBringIntoViewElements()
RunOnUIThread.Execute(() =>
{
- repeater.GetOrCreateElement(100).StartBringIntoView();
- repeater.UpdateLayout();
+ Log.Comment("\r\nStartBringIntoView for item index 100, w/ 0.5 vertical alignment.");
+ viewChangeCompletedEvent.Reset();
+ itemsRepeater.GetOrCreateElement(100).StartBringIntoView(new BringIntoViewOptions {
+ VerticalAlignmentRatio = 0.5
+ });
+ itemsRepeater.UpdateLayout();
});
Verify.IsTrue(viewChangeCompletedEvent.WaitOne(DefaultWaitTimeInMS));
IdleSynchronizer.Wait();
+
+ Log.Comment($"ScrollViewer.ViewChanged - Count: {viewChangedOffsets.Count}");
Verify.AreEqual(1, viewChangedOffsets.Count);
viewChangedOffsets.Clear();
- ValidateRealizedRange(repeater, 99, 107);
+ ValidateRealizedRange(itemsRepeater, 96, 103);
RunOnUIThread.Execute(() =>
{
- Log.Comment("Scroll into view item 105 (already realized) w/ animation.");
- repeater.TryGetElement(105).StartBringIntoView(new BringIntoViewOptions
+ Log.Comment("\r\nStartBringIntoView for item index 103 (already realized) w/ animation.");
+ viewChangeCompletedEvent.Reset();
+ itemsRepeater.TryGetElement(103).StartBringIntoView(new BringIntoViewOptions
{
VerticalAlignmentRatio = 0.5,
AnimationDesired = true
});
- repeater.UpdateLayout();
+ itemsRepeater.UpdateLayout();
});
Verify.IsTrue(viewChangeCompletedEvent.WaitOne(DefaultWaitTimeInMS));
IdleSynchronizer.Wait();
+
+ Log.Comment($"ScrollViewer.ViewChanged - Count: {viewChangedOffsets.Count}");
Verify.IsLessThanOrEqual(1, viewChangedOffsets.Count);
viewChangedOffsets.Clear();
- ValidateRealizedRange(repeater, 101, 109);
+
+ ValidateRealizedRange(itemsRepeater, 99, 107);
RunOnUIThread.Execute(() =>
{
- Log.Comment("Scroll item 0 to the top w/ animation and 0.5 vertical alignment.");
- repeater.GetOrCreateElement(0).StartBringIntoView(new BringIntoViewOptions
+ Log.Comment("\r\nStartBringIntoView for disconnected item index 0, to the top w/ unfulfilled animation and 0.5 vertical alignment.");
+ viewChangeCompletedEvent.Reset();
+ itemsRepeater.GetOrCreateElement(0).StartBringIntoView(new BringIntoViewOptions
{
VerticalAlignmentRatio = 0.5,
AnimationDesired = true
});
- repeater.UpdateLayout();
+ itemsRepeater.UpdateLayout();
});
Verify.IsTrue(viewChangeCompletedEvent.WaitOne(DefaultWaitTimeInMS));
IdleSynchronizer.Wait();
+
+ Log.Comment($"ScrollViewer.ViewChanged - Count: {viewChangedOffsets.Count}");
+ Verify.AreEqual(1, viewChangedOffsets.Count);
viewChangedOffsets.Clear();
- ValidateRealizedRange(repeater, 0, 7);
+
+ ValidateRealizedRange(itemsRepeater, 0, 6);
RunOnUIThread.Execute(() =>
{
- // You can't align the first group in the middle obviously.
+ // You can't align the first item in the middle obviously.
Verify.AreEqual(0, scroller.VerticalOffset);
- Log.Comment("Scroll to item 20.");
- repeater.GetOrCreateElement(20).StartBringIntoView(new BringIntoViewOptions
+ Log.Comment("\r\nStartBringIntoView for item index 20.");
+ viewChangeCompletedEvent.Reset();
+ itemsRepeater.GetOrCreateElement(20).StartBringIntoView(new BringIntoViewOptions
{
VerticalAlignmentRatio = 0.0
});
- repeater.UpdateLayout();
+ itemsRepeater.UpdateLayout();
});
Verify.IsTrue(viewChangeCompletedEvent.WaitOne(DefaultWaitTimeInMS));
IdleSynchronizer.Wait();
- ValidateRealizedRange(repeater, 19, 27);
+
+ Log.Comment($"ScrollViewer.ViewChanged - Count: {viewChangedOffsets.Count}");
+ Verify.AreEqual(1, viewChangedOffsets.Count);
+
+ ValidateRealizedRange(itemsRepeater, 19, 26);
}
private void ValidateRealizedRange(
- ItemsRepeater repeater,
+ ItemsRepeater itemsRepeater,
int expectedFirstItemIndex,
int expectedLastItemIndex)
{
@@ -512,12 +525,14 @@ private void ValidateRealizedRange(
int actualFirstItemIndex = -1;
int actualLastItemIndex = -1;
int itemIndex = 0;
+
RunOnUIThread.Execute(() =>
{
- var items = repeater.ItemsSource as IEnumerable;
+ var items = itemsRepeater.ItemsSource as IEnumerable;
+
foreach (var item in items)
{
- var itemElement = repeater.TryGetElement(itemIndex);
+ var itemElement = itemsRepeater.TryGetElement(itemIndex);
if (itemElement != null)
{
@@ -526,14 +541,16 @@ private void ValidateRealizedRange(
itemIndex :
actualFirstItemIndex;
actualLastItemIndex = itemIndex;
+
+ Log.Comment($"Realized Index - {itemIndex}");
}
++itemIndex;
}
});
- Log.Comment(string.Format("FirstItemIndex - {0} {1}", expectedFirstItemIndex, actualFirstItemIndex));
- Log.Comment(string.Format("LastItemIndex - {0} {1}", expectedLastItemIndex, actualLastItemIndex));
+ Log.Comment($"FirstItemIndex - {expectedFirstItemIndex} {actualFirstItemIndex}");
+ Log.Comment($"LastItemIndex - {expectedLastItemIndex} {actualLastItemIndex}");
Verify.AreEqual(expectedFirstItemIndex, actualFirstItemIndex);
Verify.AreEqual(expectedLastItemIndex, actualLastItemIndex);
}
diff --git a/src/controls/dev/Repeater/APITests/ViewManagerTests.cs b/src/controls/dev/Repeater/APITests/ViewManagerTests.cs
index c726c19d8d..55a818c877 100644
--- a/src/controls/dev/Repeater/APITests/ViewManagerTests.cs
+++ b/src/controls/dev/Repeater/APITests/ViewManagerTests.cs
@@ -281,6 +281,129 @@ public void CanChangeFocusAfterUniqueIdReset()
});
}
+ [TestMethod]
+ [TestProperty("Description", "Verifies the correct items are generated when invoking StartBringIntoView for a disconnected item.")]
+ public void ValidateBringIntoViewOperations()
+ {
+ ValidateBringIntoViewOperations(0.0 /*cacheLengths*/);
+ ValidateBringIntoViewOperations(2.0 /*cacheLengths*/);
+ }
+
+ private void ValidateBringIntoViewOperations(double cacheLengths)
+ {
+ Log.Comment("\r\nValidateBringIntoViewOperations cacheLengths: " + cacheLengths);
+
+ string strRealizedItemsIndices = null;
+ List realizedItemsIndices = null;
+ CustomItemsSource dataSource = null;
+ RunOnUIThread.Execute(() => dataSource = new CustomItemsSource(Enumerable.Range(0, 200).ToList()));
+
+ ItemsRepeater itemsRepeater = SetupRepeater(dataSource: null, itemContent: @"");
+
+ RunOnUIThread.Execute(() =>
+ {
+ realizedItemsIndices = new List();
+
+ itemsRepeater.ElementPrepared += (sender, args) =>
+ {
+ realizedItemsIndices.Add(args.Index);
+ };
+
+ itemsRepeater.ElementClearing += (sender, args) =>
+ {
+ int index = sender.GetElementIndex(args.Element);
+ realizedItemsIndices.Remove(index);
+ };
+
+ itemsRepeater.HorizontalCacheLength = cacheLengths;
+ itemsRepeater.VerticalCacheLength = cacheLengths;
+ itemsRepeater.ItemsSource = dataSource;
+ });
+
+ // The viewport size being 200px and realization window increase being 40px per measure pass,
+ // make sure there are 2.5 x cacheLengths passes to land on the final realized items.
+ // cacheLengths: number of viewports constituting the pre-fetch buffer, once completely built.
+ // Half of it is before the current viewport, and half after.
+ // viewport: 200px
+ // cacheIncrement: 40px (buffer increment per measure pass on each side)
+ // Measure passes needed to fill the pre-fetch buffer: viewport / cacheIncrement / 2 x cacheLengths = 2.5 x cacheLengths
+
+ IdleSynchronizer.Wait();
+ strRealizedItemsIndices = LogRealizedIndices(realizedItemsIndices, (int)(2.5 * cacheLengths + 1));
+ Verify.AreEqual(
+ cacheLengths == 0 ? " 0 1 2 3 4 5 6 7 8 9" : " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17",
+ strRealizedItemsIndices);
+
+ StartBringIndexIntoView(itemsRepeater, index: 99);
+ strRealizedItemsIndices = LogRealizedIndices(realizedItemsIndices, (int)(2.5 * cacheLengths + 1));
+ Verify.AreEqual(
+ cacheLengths == 0 ? " 99 100 98 97 96 95 94 93 92 91 90" : " 99 100 101 102 103 104 105 106 107 108 109 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82",
+ strRealizedItemsIndices);
+
+ StartBringIndexIntoView(itemsRepeater, index: 199);
+ strRealizedItemsIndices = LogRealizedIndices(realizedItemsIndices, (int)(2.5 * cacheLengths + 1));
+ Verify.AreEqual(
+ cacheLengths == 0 ? " 199 198 197 196 195 194 193 192 191 190" : " 199 198 197 196 195 194 193 192 191 190 189 188 187 186 185 184 183 182",
+ strRealizedItemsIndices);
+
+ StartBringIndexIntoView(itemsRepeater, index: 49);
+ strRealizedItemsIndices = LogRealizedIndices(realizedItemsIndices, (int)(2.5 * cacheLengths + 1));
+ Verify.AreEqual(
+ cacheLengths == 0 ? " 49 50 51 52 53 54 55 56 57 58 48" : " 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 48 47 46 45 44 43 42 41 40 39",
+ strRealizedItemsIndices);
+
+ StartBringIndexIntoView(itemsRepeater, index: 0);
+ strRealizedItemsIndices = LogRealizedIndices(realizedItemsIndices, (int)(2.5 * cacheLengths + 1));
+ Verify.AreEqual(
+ cacheLengths == 0 ? " 0 1 2 3 4 5 6 7 8 9" : " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17",
+ strRealizedItemsIndices);
+ }
+
+ private void StartBringIndexIntoView(ItemsRepeater itemsRepeater, int index)
+ {
+ RunOnUIThread.Execute(() =>
+ {
+ Log.Comment("\r\nItemsRepeater.GetOrCreateElement(" + index + ")");
+ var item = itemsRepeater.GetOrCreateElement(index);
+
+ // Make sure the newly created item is measured so that its size is
+ // identified and can be used to bring it entirely into view.
+ Log.Comment("UIElement.UpdateLayout()");
+ item.UpdateLayout();
+
+ Log.Comment("UIElement.StartBringIntoView()");
+ item.StartBringIntoView();
+ });
+
+ IdleSynchronizer.Wait();
+ }
+
+ private string LogRealizedIndices(List realizedItemsIndices, int ticks)
+ {
+ string strRealizedItemsIndices = null;
+
+ do
+ {
+ RunOnUIThread.Execute(() =>
+ {
+ strRealizedItemsIndices = string.Empty;
+
+ foreach (int i in realizedItemsIndices)
+ {
+ strRealizedItemsIndices += " " + i;
+ }
+
+ Log.Comment("Realized indices:" + strRealizedItemsIndices);
+ });
+
+ ticks--;
+ CompositionPropertySpy.SynchronouslyTickUIThread(1);
+ }
+ while (ticks >= 0);
+
+ return strRealizedItemsIndices;
+ }
+
[TestMethod]
public void ValidateElementEvents()
{
@@ -605,7 +728,7 @@ public void ValidateFocusMoveOnElementCleared()
dataSource = new CustomItemsSource(Enumerable.Range(0, 5).ToList());
});
- repeater = SetupRepeater(dataSource, "");
+ repeater = SetupRepeater(dataSource, "");
// dataSource: 0 1 2 3 4
// Index 0 deleted, focus should be on the new element which has index 0
@@ -650,7 +773,7 @@ public void ValidateFocusMoveOnElementClearedWithUniqueIds()
dataSource = new CustomItemsSourceWithUniqueId(Enumerable.Range(0, 5).ToList());
});
- repeater = SetupRepeater(dataSource, "");
+ repeater = SetupRepeater(dataSource, "");
// dataSource: 0 1 2 3 4
// Index 0 deleted, focus should be on the new element which has index 0
@@ -790,7 +913,7 @@ private VirtualizingLayout CreateLayout(ItemsRepeater repeater)
return layout;
}
- private ItemsRepeater SetupRepeater(object dataSource, string itemContent= @"")
+ private ItemsRepeater SetupRepeater(object dataSource=null, string itemContent= @"")
{
VirtualizingLayout layout = null;
RunOnUIThread.Execute(() => layout = new StackLayout());
@@ -800,21 +923,20 @@ private ItemsRepeater SetupRepeater(object dataSource, string itemContent= @"", out scrollViewer);
+ return SetupRepeater( dataSource, layout, @"", out scrollViewer);
}
private ItemsRepeater SetupRepeater(object dataSource, VirtualizingLayout layout, string itemContent, out ScrollViewer scrollViewer)
{
- ItemsRepeater repeater = null;
+ ItemsRepeater itemsRepeater = null;
ScrollViewer sv = null;
RunOnUIThread.Execute(() =>
{
var elementFactory = new RecyclingElementFactory();
elementFactory.RecyclePool = new RecyclePool();
- elementFactory.Templates["Item"] = (DataTemplate)XamlReader.Load(
- @" " + itemContent + @"");
+ elementFactory.Templates["Item"] = XamlReader.Load(@"" + itemContent + @"") as DataTemplate;
- repeater = new ItemsRepeater()
+ itemsRepeater = new ItemsRepeater()
{
ItemsSource = dataSource,
ItemTemplate = elementFactory,
@@ -825,7 +947,7 @@ private ItemsRepeater SetupRepeater(object dataSource, VirtualizingLayout layout
sv = new ScrollViewer
{
- Content = repeater
+ Content = itemsRepeater
};
Content = new ItemsRepeaterScrollHost()
@@ -838,7 +960,7 @@ private ItemsRepeater SetupRepeater(object dataSource, VirtualizingLayout layout
IdleSynchronizer.Wait();
scrollViewer = sv;
- return repeater;
+ return itemsRepeater;
}
private int DefaultWaitTime = 2000;
diff --git a/src/controls/dev/Repeater/ViewportManagerWithPlatformFeatures.cpp b/src/controls/dev/Repeater/ViewportManagerWithPlatformFeatures.cpp
index c58946ec41..81e2cb673c 100644
--- a/src/controls/dev/Repeater/ViewportManagerWithPlatformFeatures.cpp
+++ b/src/controls/dev/Repeater/ViewportManagerWithPlatformFeatures.cpp
@@ -61,7 +61,7 @@ winrt::UIElement ViewportManagerWithPlatformFeatures::SuggestedAnchor() const
{
ITEMSREPEATER_TRACE_VERBOSE(nullptr, TRACE_MSG_METH_STR_STR, METH_NAME, this, GetLayoutId().data(), L"SuggestedAnchor returns null.");
}
-#endif
+#endif // DBG
}
#ifdef DBG
else
@@ -69,7 +69,7 @@ winrt::UIElement ViewportManagerWithPlatformFeatures::SuggestedAnchor() const
// Since we have an anchor element, we do not want the scroll anchor provider to start anchoring some other element.
ITEMSREPEATER_TRACE_INFO(nullptr, TRACE_MSG_METH_STR_STR_PTR, METH_NAME, this, GetLayoutId().data(), L"SuggestedAnchor returns non-null m_makeAnchorElement.", m_makeAnchorElement);
}
-#endif
+#endif // DBG
return suggestedAnchor;
}
@@ -201,6 +201,13 @@ void ViewportManagerWithPlatformFeatures::SetUnshiftableShift(float unshiftableS
void ViewportManagerWithPlatformFeatures::SetLayoutExtent(const winrt::Rect& layoutExtent)
{
+#ifdef DBG
+ ITEMSREPEATER_TRACE_INFO(nullptr, TRACE_MSG_METH_STR_STR_FLT_FLT, METH_NAME, this,
+ GetLayoutId().data(), L"layoutExtent:", layoutExtent.X, layoutExtent.Y);
+
+ TraceFieldsDbg();
+#endif // DBG
+
SetExpectedViewportShift(m_expectedViewportShift.X + m_layoutExtent.X - layoutExtent.X, m_expectedViewportShift.Y + m_layoutExtent.Y - layoutExtent.Y);
// We tolerate viewport imprecisions up to 1 pixel to avoid invaliding layout too much.
@@ -510,7 +517,7 @@ void ViewportManagerWithPlatformFeatures::OnMakeAnchor(const winrt::UIElement& a
}
else
{
- ITEMSREPEATER_TRACE_INFO(nullptr, TRACE_MSG_METH_STR_STR_PTR, METH_NAME, this, GetLayoutId().data(), L"%Sets m_makeAnchorElement.", anchor);
+ ITEMSREPEATER_TRACE_INFO(nullptr, TRACE_MSG_METH_STR_STR_PTR, METH_NAME, this, GetLayoutId().data(), L"Sets m_makeAnchorElement.", anchor);
}
#endif // DBG
@@ -583,7 +590,22 @@ void ViewportManagerWithPlatformFeatures::OnCompositionTargetRendering(const win
m_renderingToken.revoke();
m_isBringIntoViewInProgress = false;
- m_makeAnchorElement.set(nullptr);
+
+ if (m_makeAnchorElement)
+ {
+ m_makeAnchorElement.set(nullptr);
+
+ if (m_isAnchorOutsideRealizedRange)
+ {
+ m_isAnchorOutsideRealizedRange = false;
+
+ // During the bring-into-view operation, the layout anchor was positioned at the top/left
+ // of the viewport (see ViewportManagerWithPlatformFeatures::GetLayoutVisibleWindow()).
+ // Now it may move within the viewport and require different items to be generated given
+ // its final position. Thus a new measure pass is requested.
+ TryInvalidateMeasure();
+ }
+ }
// Now that the item has been brought into view, we can let the anchor provider pick a new anchor.
for (const auto& child : m_owner->Children())
@@ -611,7 +633,13 @@ void ViewportManagerWithPlatformFeatures::ResetScrollers()
void ViewportManagerWithPlatformFeatures::OnCacheBuildActionCompleted()
{
- m_cacheBuildActionOutstanding = false;
+ if (m_cacheBuildActionOutstanding)
+ {
+ ITEMSREPEATER_TRACE_VERBOSE_DBG(nullptr, TRACE_MSG_METH_STR_STR, METH_NAME, this, GetLayoutId().data(), L"m_cacheBuildActionOutstanding reset.");
+
+ m_cacheBuildActionOutstanding = false;
+ }
+
if (!m_managingViewportDisabled)
{
m_owner->InvalidateMeasure();
@@ -833,12 +861,17 @@ bool ViewportManagerWithPlatformFeatures::UpdateViewport(winrt::Rect const& effe
void ViewportManagerWithPlatformFeatures::ResetLayoutRealizationWindowCacheBuffer()
{
+ ITEMSREPEATER_TRACE_INFO_DBG(nullptr, TRACE_MSG_METH_STR, METH_NAME, this, GetLayoutId().data());
+
ResetCacheBuffer(false /*registerCacheBuildWork*/);
}
void ViewportManagerWithPlatformFeatures::ResetCacheBuffer(bool registerCacheBuildWork)
{
#ifdef DBG
+ ITEMSREPEATER_TRACE_INFO(nullptr, TRACE_MSG_METH_STR_STR_INT, METH_NAME, this,
+ GetLayoutId().data(), L"registerCacheBuildWork:", registerCacheBuildWork);
+
if (m_horizontalCacheBufferPerSide != 0.0)
{
ITEMSREPEATER_TRACE_INFO(nullptr, TRACE_MSG_METH_STR_STR_DBL, METH_NAME, this,
@@ -924,8 +957,8 @@ void ViewportManagerWithPlatformFeatures::RegisterPreparedAndArrangedElementsAsS
void ViewportManagerWithPlatformFeatures::RegisterCacheBuildWork()
{
MUX_ASSERT(!m_managingViewportDisabled);
- if (m_owner->Layout() &&
- !m_cacheBuildActionOutstanding)
+
+ if (!m_cacheBuildActionOutstanding)
{
// We capture 'owner' (a strong reference on ItemsRepeater) to make sure ItemsRepeater is still around
// when the async action completes. By protecting ItemsRepeater, we also ensure that this instance
@@ -938,7 +971,17 @@ void ViewportManagerWithPlatformFeatures::RegisterCacheBuildWork()
{
OnCacheBuildActionCompleted();
});
+
+ ITEMSREPEATER_TRACE_VERBOSE_DBG(nullptr, TRACE_MSG_METH_STR_STR_INT, METH_NAME, this,
+ GetLayoutId().data(), L"m_cacheBuildActionOutstanding set:", m_cacheBuildActionOutstanding);
}
+#ifdef DBG
+ else
+ {
+ ITEMSREPEATER_TRACE_VERBOSE(nullptr, TRACE_MSG_METH_STR_STR, METH_NAME, this,
+ GetLayoutId().data(), L"m_cacheBuildActionOutstanding already set.");
+ }
+#endif // DBG
}
void ViewportManagerWithPlatformFeatures::TryInvalidateMeasure()
diff --git a/src/controls/dev/ScrollPresenter/InteractionTests/ScrollPresenterTestsWithInputHelper.cs b/src/controls/dev/ScrollPresenter/InteractionTests/ScrollPresenterTestsWithInputHelper.cs
index c3646f09b9..4fc6114833 100644
--- a/src/controls/dev/ScrollPresenter/InteractionTests/ScrollPresenterTestsWithInputHelper.cs
+++ b/src/controls/dev/ScrollPresenter/InteractionTests/ScrollPresenterTestsWithInputHelper.cs
@@ -50,10 +50,9 @@ public void TestCleanup()
TestCleanupHelper.Cleanup();
}
- //[TestMethod]
- //[TestProperty("Description", "Pans a Rectangle in a ScrollPresenter, with railing.")]
- //[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Pans a Rectangle in a ScrollPresenter, with railing.")]
+ [TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
public void PanWithRailing()
{
const double minVerticalScrollPercent = 50.0;
@@ -132,10 +131,9 @@ public void PanWithRailing()
}
}
- //[TestMethod]
- //[TestProperty("Description", "Pans an Image in a ScrollPresenter, without railing.")]
- //[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Pans an Image in a ScrollPresenter, without railing.")]
+ [TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
public void PanWithoutRailing()
{
const double minHorizontalScrollPercent = 35.0;
@@ -217,9 +215,8 @@ public void PanWithoutRailing()
}
}
- //[TestMethod]
- //[TestProperty("Description", "Scrolls a Rectangle in a ScrollPresenter, with the mouse wheel.")]
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Scrolls a Rectangle in a ScrollPresenter, with the mouse wheel.")]
public void ScrollWithMouseWheel()
{
double minVerticalScrollPercent = 5.0;
@@ -586,20 +583,17 @@ public void StretchImageWithMouseWheel()
}
}
- //[TestMethod]
- //[TestProperty("Description", "Reduce the Content size while it is far-anchored and overpanned.")]
- //[TestProperty("Ignore", "True")] // 24178380
- //[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Reduce the Content size while it is far-anchored and overpanned.")]
+ [TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
public void OverpanWithAnchoredSkrinkingContent()
{
OverpanWithAnchoredSkrinkingContent(isForHorizontalDirection: true);
}
- //[TestMethod]
- //[TestProperty("Description", "Reduce the Content size while it is far-anchored and overpanned.")]
- //[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Reduce the Content size while it is far-anchored and overpanned.")]
+ [TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
public void OverpanWithAnchoredSkrinkingContentVert()
{
OverpanWithAnchoredSkrinkingContent(isForHorizontalDirection: false);
@@ -744,7 +738,7 @@ private void OverpanWithAnchoredSkrinkingContent(bool isForHorizontalDirection)
//[TestMethod]
//[TestProperty("Description", "Pans an inner ScrollViewer and chains to an outer ScrollPresenter.")]
//[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ // Bug 51897603: ScrollPresenter: Fix and re-enable interaction tests
public void PanWithChainingFromScrollViewerToScrollPresenter()
{
Log.Comment("Selecting ScrollPresenter tests");
@@ -816,7 +810,7 @@ public void PanWithChainingFromScrollViewerToScrollPresenter()
//[TestMethod]
//[TestProperty("Description", "Pans an inner ScrollPresenter and chains to an outer ScrollViewer.")]
//[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ // Bug 51897603: ScrollPresenter: Fix and re-enable interaction tests
public void PanWithChainingFromScrollPresenterToScrollViewer()
{
// Inner ScrollPresenter uses ChainingMode.Always
@@ -826,7 +820,7 @@ public void PanWithChainingFromScrollPresenterToScrollViewer()
//[TestMethod]
//[TestProperty("Description", "Pans an inner ScrollPresenter and chains to an outer ScrollViewer.")]
//[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ // Bug 51897603: ScrollPresenter: Fix and re-enable interaction tests
public void PanWithChainingFromScrollPresenterToScrollViewer_Auto()
{
// Inner ScrollPresenter uses ChainingMode.Auto
@@ -924,7 +918,7 @@ public void PanWithChainingFromScrollPresenterToScrollViewerWithChainingMode(boo
//[TestMethod]
//[TestProperty("Description", "Attempts to scroll when ManipulationMode is not System.")]
//[TestProperty("TestPass:MinOSVer", WindowsOSVersion.RS5)] // Touch input injection is only supported on RS5 and up
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ // Bug 51897603: ScrollPresenter: Fix and re-enable interaction tests
public void ScrollWithNonSystemManipulationMode()
{
Log.Comment("Selecting ScrollPresenter tests");
@@ -1082,24 +1076,21 @@ public void PanTowardsTwoManditoryIrregularSnapPoint_Far()
MoveTowardsTwoManditoryIrregularSnapPoint(alignment: ScrollSnapPointsAlignment.Far, withTouch: true);
}
- //[TestMethod]
- //[TestProperty("Description", "Apply two mandatory irregular snap points to the scrollPresenter and snap to them using mouse-wheel input.")]
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Apply two mandatory irregular snap points to the scrollPresenter and snap to them using mouse-wheel input.")]
public void ScrollTowardsTwoManditoryIrregularSnapPoint_Near()
{
MoveTowardsTwoManditoryIrregularSnapPoint(alignment: ScrollSnapPointsAlignment.Near, withTouch: false);
}
- //[TestMethod]
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
public void ScrollTowardsTwoManditoryIrregularSnapPoint_Center()
{
MoveTowardsTwoManditoryIrregularSnapPoint(alignment: ScrollSnapPointsAlignment.Center, withTouch: false);
}
- //[TestMethod]
- //[TestProperty("Description", "Apply two mandatory irregular snap points to the scrollPresenter and snap to them using mouse-wheel input.")]
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Apply two mandatory irregular snap points to the scrollPresenter and snap to them using mouse-wheel input.")]
public void ScrollTowardsTwoManditoryIrregularSnapPoint_Far()
{
MoveTowardsTwoManditoryIrregularSnapPoint(alignment: ScrollSnapPointsAlignment.Far, withTouch: false);
@@ -1248,25 +1239,22 @@ public void PanWithinARepeatedMandatorySnapPointWithDifferentOffset_Far()
MoveWithinARepeatedMandatorySnapPoint(withOffsetEqualToStart: false, alignment: ScrollSnapPointsAlignment.Far, withTouch: true);
}
- //[TestMethod]
- //[TestProperty("Description", "Apply a single mandatory repeated snap point across the scrollPresenter extent and snap to it using mouse-wheel input.")]
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Apply a single mandatory repeated snap point across the scrollPresenter extent and snap to it using mouse-wheel input.")]
public void ScrollWithinARepeatedMandatorySnapPoint_Near()
{
MoveWithinARepeatedMandatorySnapPoint(withOffsetEqualToStart: false, alignment: ScrollSnapPointsAlignment.Near, withTouch: false);
}
- //[TestMethod]
- //[TestProperty("Description", "Apply a single mandatory repeated snap point across the scrollPresenter extent and snap to it using mouse-wheel input.")]
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Apply a single mandatory repeated snap point across the scrollPresenter extent and snap to it using mouse-wheel input.")]
public void ScrollWithinARepeatedMandatorySnapPoint_Center()
{
MoveWithinARepeatedMandatorySnapPoint(withOffsetEqualToStart: false, alignment: ScrollSnapPointsAlignment.Center, withTouch: false);
}
- //[TestMethod]
- //[TestProperty("Description", "Apply a single mandatory repeated snap point across the scrollPresenter extent and snap to it using mouse-wheel input.")]
- // Bug 24357468: DCPP: MUXControls.InteractionTests.ScrollPresenterTestsWithInputHelper is failing
+ [TestMethod]
+ [TestProperty("Description", "Apply a single mandatory repeated snap point across the scrollPresenter extent and snap to it using mouse-wheel input.")]
public void ScrollWithinARepeatedMandatorySnapPoint_Far()
{
MoveWithinARepeatedMandatorySnapPoint(withOffsetEqualToStart: false, alignment: ScrollSnapPointsAlignment.Far, withTouch: false);
diff --git a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml
index 91ef521f99..dedc3b17d8 100644
--- a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml
+++ b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml
@@ -9,21 +9,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ BorderBrush="{ThemeResource SystemChromeGrayColor}" BorderThickness="1"
+ RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"
+ ColumnDefinitions="Auto,Auto,Auto,Auto,Auto">
@@ -336,34 +286,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ BorderBrush="{ThemeResource SystemChromeGrayColor}" BorderThickness="1"
+ RowDefinitions="Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto"
+ ColumnDefinitions="Auto, Auto, Auto, Auto, Auto">
@@ -459,67 +384,20 @@
+
-
-
-
-
-
-
-
+ BorderBrush="{ThemeResource SystemChromeGrayColor}" BorderThickness="1"
+ RowDefinitions="Auto, Auto"
+ ColumnDefinitions="Auto">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -661,15 +539,9 @@
-
-
-
-
-
-
-
-
+ BorderBrush="{ThemeResource SystemChromeGrayColor}" BorderThickness="1"
+ RowDefinitions="Auto, Auto, *"
+ ColumnDefinitions="*">
@@ -683,24 +555,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ BorderBrush="{ThemeResource SystemChromeGrayColor}" BorderThickness="1"
+ RowDefinitions="Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto"
+ ColumnDefinitions="Auto">
diff --git a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml.cs b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml.cs
index b5bdb16bcf..a9a57dd428 100644
--- a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml.cs
+++ b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterDynamicPage.xaml.cs
@@ -79,6 +79,10 @@ public QueuedOperation(QueuedOperationType type, string value)
private StackPanel verticalStackPanel;
private ScrollPresenter dynamicScrollPresenter = null;
private ScrollPresenter scrollPresenter = null;
+ private PointerEventHandler contentPointerPressedEventHandler = null;
+ private PointerEventHandler contentPointerReleasedEventHandler = null;
+ private PointerEventHandler contentPointerCanceledEventHandler = null;
+ private PointerEventHandler contentPointerCaptureLostEventHandler = null;
public ScrollPresenterDynamicPage()
{
@@ -300,6 +304,16 @@ private void ChkLogContentEffectiveViewportChangedEvent_Unchecked(object sender,
UnhookContentEffectiveViewportChanged();
}
+ private void ChkLogContentPointerEvents_Checked(object sender, RoutedEventArgs e)
+ {
+ HookContentPointerEvents();
+ }
+
+ private void ChkLogContentPointerEvents_Unchecked(object sender, RoutedEventArgs e)
+ {
+ UnhookContentPointerEvents();
+ }
+
private void HookContentEffectiveViewportChanged()
{
if (scrollPresenter != null)
@@ -324,6 +338,41 @@ private void UnhookContentEffectiveViewportChanged()
}
}
+ private void HookContentPointerEvents()
+ {
+ if (scrollPresenter != null)
+ {
+ UIElement contentAsUIE = scrollPresenter.Content as UIElement;
+ if (contentAsUIE != null)
+ {
+ contentPointerPressedEventHandler = new PointerEventHandler(Content_PointerPressed);
+ contentPointerReleasedEventHandler = new PointerEventHandler(Content_PointerReleased);
+ contentPointerCanceledEventHandler = new PointerEventHandler(Content_PointerCanceled);
+ contentPointerCaptureLostEventHandler = new PointerEventHandler(Content_PointerCaptureLost);
+
+ contentAsUIE.AddHandler(UIElement.PointerPressedEvent, contentPointerPressedEventHandler, true);
+ contentAsUIE.AddHandler(UIElement.PointerReleasedEvent, contentPointerReleasedEventHandler, true);
+ contentAsUIE.AddHandler(UIElement.PointerCanceledEvent, contentPointerCanceledEventHandler, true);
+ contentAsUIE.AddHandler(UIElement.PointerCaptureLostEvent, contentPointerCaptureLostEventHandler, true);
+ }
+ }
+ }
+
+ private void UnhookContentPointerEvents()
+ {
+ if (scrollPresenter != null)
+ {
+ UIElement contentAsUIE = scrollPresenter.Content as UIElement;
+ if (contentAsUIE != null)
+ {
+ contentAsUIE.RemoveHandler(UIElement.PointerPressedEvent, contentPointerPressedEventHandler);
+ contentAsUIE.RemoveHandler(UIElement.PointerReleasedEvent, contentPointerReleasedEventHandler);
+ contentAsUIE.RemoveHandler(UIElement.PointerCanceledEvent, contentPointerCanceledEventHandler);
+ contentAsUIE.RemoveHandler(UIElement.PointerCaptureLostEvent, contentPointerCaptureLostEventHandler);
+ }
+ }
+ }
+
private void Content_EffectiveViewportChanged(FrameworkElement sender, EffectiveViewportChangedEventArgs args)
{
AppendAsyncEventMessage("Content_EffectiveViewportChanged: BringIntoViewDistance=" +
@@ -331,6 +380,26 @@ private void Content_EffectiveViewportChanged(FrameworkElement sender, Effective
args.EffectiveViewport.ToString() + ", MaxViewport=" + args.MaxViewport.ToString());
}
+ private void Content_PointerPressed(object sender, PointerRoutedEventArgs e)
+ {
+ AppendAsyncEventMessage("Content_PointerPressed: PointerId=" + e.Pointer.PointerId);
+ }
+
+ private void Content_PointerReleased(object sender, PointerRoutedEventArgs e)
+ {
+ AppendAsyncEventMessage("Content_PointerReleased: PointerId=" + e.Pointer.PointerId);
+ }
+
+ private void Content_PointerCanceled(object sender, PointerRoutedEventArgs e)
+ {
+ AppendAsyncEventMessage("Content_PointerCanceled: PointerId=" + e.Pointer.PointerId);
+ }
+
+ private void Content_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
+ {
+ AppendAsyncEventMessage("Content_PointerCaptureLost: PointerId=" + e.Pointer.PointerId);
+ }
+
private void MUXControlsTestHooks_LoggingMessage(object sender, MUXControlsTestHooksLoggingMessageEventArgs args)
{
// Cut off the terminating new line.
@@ -796,6 +865,11 @@ private void CmbContent_SelectionChanged(object sender, SelectionChangedEventArg
UnhookContentEffectiveViewportChanged();
}
+ if (chkLogContentPointerEvents.IsChecked == true)
+ {
+ UnhookContentPointerEvents();
+ }
+
scrollPresenter.Content = newContent;
if (chkPreserveProperties.IsChecked == false)
@@ -809,6 +883,11 @@ private void CmbContent_SelectionChanged(object sender, SelectionChangedEventArg
{
HookContentEffectiveViewportChanged();
}
+
+ if (chkLogContentPointerEvents.IsChecked == true)
+ {
+ HookContentPointerEvents();
+ }
}
catch (Exception ex)
{
diff --git a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterScrollSnapPointsPage.xaml.cs b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterScrollSnapPointsPage.xaml.cs
index 7d1b6a5825..632f24d14a 100644
--- a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterScrollSnapPointsPage.xaml.cs
+++ b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterScrollSnapPointsPage.xaml.cs
@@ -57,8 +57,8 @@ private void ScrollPresenterScrollSnapPointsPage_Loaded(object sender, RoutedEve
private void MarkupScrollPresenter_ViewChanged(ScrollPresenter sender, object args)
{
- this.txtScrollPresenterOffset.Text = this.markupScrollPresenter.VerticalOffset.ToString();
- this.txtScrollPresenterZoomFactor.Text = this.markupScrollPresenter.ZoomFactor.ToString();
+ this.txtScrollPresenterOffset.Text = this.markupScrollPresenter.VerticalOffset.ToString("F2");
+ this.txtScrollPresenterZoomFactor.Text = this.markupScrollPresenter.ZoomFactor.ToString("F2");
}
private void MarkupScrollPresenter_StateChanged(ScrollPresenter sender, object args)
diff --git a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterZoomSnapPointsPage.xaml.cs b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterZoomSnapPointsPage.xaml.cs
index 027c946f1d..abb6a42d40 100644
--- a/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterZoomSnapPointsPage.xaml.cs
+++ b/src/controls/dev/ScrollPresenter/TestUI/ScrollPresenterZoomSnapPointsPage.xaml.cs
@@ -43,9 +43,9 @@ private void ScrollPresenterZoomSnapPointsPage_Loaded(object sender, RoutedEvent
private void MarkupScrollPresenter_ViewChanged(ScrollPresenter sender, object args)
{
- this.txtScrollPresenterHorizontalOffset.Text = this.markupScrollPresenter.HorizontalOffset.ToString();
- this.txtScrollPresenterVerticalOffset.Text = this.markupScrollPresenter.VerticalOffset.ToString();
- this.txtScrollPresenterZoomFactor.Text = this.markupScrollPresenter.ZoomFactor.ToString();
+ this.txtScrollPresenterHorizontalOffset.Text = this.markupScrollPresenter.HorizontalOffset.ToString("F2");
+ this.txtScrollPresenterVerticalOffset.Text = this.markupScrollPresenter.VerticalOffset.ToString("F2");
+ this.txtScrollPresenterZoomFactor.Text = this.markupScrollPresenter.ZoomFactor.ToString("F2");
}
private void MarkupScrollPresenter_StateChanged(ScrollPresenter sender, object args)
diff --git a/src/controls/dev/TitleBar/TestUI/TitleBarPage.xaml b/src/controls/dev/TitleBar/TestUI/TitleBarPage.xaml
index 8052da162c..d84a2f9e48 100644
--- a/src/controls/dev/TitleBar/TestUI/TitleBarPage.xaml
+++ b/src/controls/dev/TitleBar/TestUI/TitleBarPage.xaml
@@ -16,6 +16,17 @@
+
+
+
+
+
diff --git a/src/controls/dev/TitleBar/TitleBar.cpp b/src/controls/dev/TitleBar/TitleBar.cpp
index d3cede6cfd..bab8c62d6a 100644
--- a/src/controls/dev/TitleBar/TitleBar.cpp
+++ b/src/controls/dev/TitleBar/TitleBar.cpp
@@ -69,6 +69,10 @@ void TitleBar::OnApplyTemplate()
UpdatePaneToggleButton();
UpdateTheme();
UpdateTitle();
+ UpdateSubtitle();
+ UpdateHeader();
+ UpdateContent();
+ UpdateFooter();
UpdateInteractableElementsList();
}
@@ -162,6 +166,12 @@ void TitleBar::OnInputActivationChanged(const winrt::InputActivationListener& se
isDeactivated ? s_paneToggleButtonDeactivatedVisualStateName : s_paneToggleButtonVisibleVisualStateName, false);
}
+ if (IconSource() != nullptr)
+ {
+ winrt::VisualStateManager::GoToState(*this,
+ isDeactivated ? s_iconDeactivatedVisualStateName : s_iconVisibleVisualStateName, false);
+ }
+
if (!Title().empty())
{
winrt::VisualStateManager::GoToState(*this,
@@ -173,6 +183,24 @@ void TitleBar::OnInputActivationChanged(const winrt::InputActivationListener& se
winrt::VisualStateManager::GoToState(*this,
isDeactivated ? s_subtitleTextDeactivatedVisualStateName : s_subtitleTextVisibleVisualStateName, false);
}
+
+ if (Header() != nullptr)
+ {
+ winrt::VisualStateManager::GoToState(*this,
+ isDeactivated ? s_headerDeactivatedVisualStateName : s_headerVisibleVisualStateName, false);
+ }
+
+ if (Content() != nullptr)
+ {
+ winrt::VisualStateManager::GoToState(*this,
+ isDeactivated ? s_contentDeactivatedVisualStateName : s_contentVisibleVisualStateName, false);
+ }
+
+ if (Footer() != nullptr)
+ {
+ winrt::VisualStateManager::GoToState(*this,
+ isDeactivated ? s_footerDeactivatedVisualStateName : s_footerVisibleVisualStateName, false);
+ }
}
void TitleBar::OnBackButtonClick(winrt::IInspectable const& sender, winrt::RoutedEventArgs const& args)
diff --git a/src/controls/dev/TitleBar/TitleBar.h b/src/controls/dev/TitleBar/TitleBar.h
index 6785c3cdac..97a05dec08 100644
--- a/src/controls/dev/TitleBar/TitleBar.h
+++ b/src/controls/dev/TitleBar/TitleBar.h
@@ -89,24 +89,28 @@ class TitleBar :
static constexpr std::wstring_view s_expandedHeightVisualStateName{ L"ExpandedHeight"sv };
static constexpr std::wstring_view s_iconVisibleVisualStateName{ L"IconVisible"sv };
static constexpr std::wstring_view s_iconCollapsedVisualStateName{ L"IconCollapsed"sv };
- static constexpr std::wstring_view s_backButtonDeactivatedVisualStateName{ L"BackButtonDeactivated"sv };
+ static constexpr std::wstring_view s_iconDeactivatedVisualStateName{ L"IconDeactivated"sv };
static constexpr std::wstring_view s_backButtonVisibleVisualStateName{ L"BackButtonVisible"sv };
static constexpr std::wstring_view s_backButtonCollapsedVisualStateName{ L"BackButtonCollapsed"sv };
- static constexpr std::wstring_view s_paneToggleButtonDeactivatedVisualStateName{ L"PaneToggleButtonDeactivated"sv };
+ static constexpr std::wstring_view s_backButtonDeactivatedVisualStateName{ L"BackButtonDeactivated"sv };
static constexpr std::wstring_view s_paneToggleButtonVisibleVisualStateName{ L"PaneToggleButtonVisible"sv };
static constexpr std::wstring_view s_paneToggleButtonCollapsedVisualStateName{ L"PaneToggleButtonCollapsed"sv };
- static constexpr std::wstring_view s_titleTextDeactivatedVisualStateName{ L"TitleTextDeactivated"sv };
+ static constexpr std::wstring_view s_paneToggleButtonDeactivatedVisualStateName{ L"PaneToggleButtonDeactivated"sv };
static constexpr std::wstring_view s_titleTextVisibleVisualStateName{ L"TitleTextVisible"sv };
static constexpr std::wstring_view s_titleTextCollapsedVisualStateName{ L"TitleTextCollapsed"sv };
- static constexpr std::wstring_view s_subtitleTextDeactivatedVisualStateName{ L"SubtitleTextDeactivated"sv };
+ static constexpr std::wstring_view s_titleTextDeactivatedVisualStateName{ L"TitleTextDeactivated"sv };
static constexpr std::wstring_view s_subtitleTextVisibleVisualStateName{ L"SubtitleTextVisible"sv };
static constexpr std::wstring_view s_subtitleTextCollapsedVisualStateName{ L"SubtitleTextCollapsed"sv };
+ static constexpr std::wstring_view s_subtitleTextDeactivatedVisualStateName{ L"SubtitleTextDeactivated"sv };
static constexpr std::wstring_view s_headerVisibleVisualStateName{ L"HeaderVisible"sv };
static constexpr std::wstring_view s_headerCollapsedVisualStateName{ L"HeaderCollapsed"sv };
+ static constexpr std::wstring_view s_headerDeactivatedVisualStateName{ L"HeaderDeactivated"sv };
static constexpr std::wstring_view s_contentVisibleVisualStateName{ L"ContentVisible"sv };
static constexpr std::wstring_view s_contentCollapsedVisualStateName{ L"ContentCollapsed"sv };
+ static constexpr std::wstring_view s_contentDeactivatedVisualStateName{ L"ContentDeactivated"sv };
static constexpr std::wstring_view s_footerVisibleVisualStateName{ L"FooterVisible"sv };
static constexpr std::wstring_view s_footerCollapsedVisualStateName{ L"FooterCollapsed"sv };
+ static constexpr std::wstring_view s_footerDeactivatedVisualStateName{ L"FooterDeactivated"sv };
static constexpr std::wstring_view s_titleBarButtonForegroundColorName{ L"TitleBarButtonForegroundColor"sv };
static constexpr std::wstring_view s_titleBarButtonBackgroundColorName{ L"TitleBarButtonBackgroundColor"sv };
diff --git a/src/controls/dev/TitleBar/TitleBar.xaml b/src/controls/dev/TitleBar/TitleBar.xaml
index b871a9561e..07b5091a79 100644
--- a/src/controls/dev/TitleBar/TitleBar.xaml
+++ b/src/controls/dev/TitleBar/TitleBar.xaml
@@ -44,22 +44,34 @@
-
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
@@ -87,27 +99,39 @@
-
+
-
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
@@ -214,7 +238,7 @@
Grid.Column="5"
Text="{TemplateBinding Subtitle}"
Style="{StaticResource CaptionTextBlockStyle}"
- Foreground="{ThemeResource SubtitleBarForegroundBrush}"
+ Foreground="{ThemeResource TitleBarSubtitleForegroundBrush}"
Margin="0,0,16,0"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"
diff --git a/src/controls/dev/TitleBar/TitleBar_themeresources.xaml b/src/controls/dev/TitleBar/TitleBar_themeresources.xaml
index 7074d5f381..5850b2d010 100644
--- a/src/controls/dev/TitleBar/TitleBar_themeresources.xaml
+++ b/src/controls/dev/TitleBar/TitleBar_themeresources.xaml
@@ -9,8 +9,8 @@
-
-
+
+
#FFFFFF
#FFFFFF
#CFCFCF
@@ -24,8 +24,8 @@
-
-
+
+
#191919
#191919
#606060
@@ -39,8 +39,8 @@
-
-
+
+
@@ -53,6 +53,8 @@
+ 0.5
+