Created
October 9, 2016 19:58
-
-
Save rootasjey/f0f9b28a1c2eded5a7c9da9f209db3e5 to your computer and use it in GitHub Desktop.
Retrieve XAML control from code behind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Windows.Foundation; | |
using Windows.UI.Xaml; | |
using Windows.UI.Xaml.Controls; | |
using Windows.UI.Xaml.Controls.Primitives; | |
using Windows.UI.Xaml.Media; | |
namespace appNamespace.Helpers { | |
public static class VisualTreeExtensions { | |
public static T GetChildOfType<T>(this DependencyObject depObj) where T : DependencyObject { | |
if (depObj == null) return null; | |
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { | |
var child = VisualTreeHelper.GetChild(depObj, i); | |
var result = (child as T) ?? GetChildOfType<T>(child); | |
if (result != null) return result; | |
} | |
return null; | |
} | |
public static T GetParentOfType<T>(this DependencyObject depObj) where T : DependencyObject { | |
if (depObj == null) return null; | |
var parent = VisualTreeHelper.GetParent(depObj); | |
var result = (parent as T) ?? GetParentOfType<T>(parent); | |
if (result != null) return result; | |
return null; | |
} | |
public async static Task ScrollToIndex(this ListViewBase listViewBase, int index) { | |
bool isVirtualizing = default(bool); | |
double previousHorizontalOffset = default(double), previousVerticalOffset = default(double); | |
// get the ScrollViewer withtin the ListView/GridView | |
//var scrollViewer = listViewBase.GetScrollViewer(); | |
var scrollViewer = listViewBase.GetChildOfType<ScrollViewer>(); | |
// get the SelectorItem to scroll to | |
var selectorItem = listViewBase.ContainerFromIndex(index) as SelectorItem; | |
// when it's null, means virtualization is on and the item hasn't been realized yet | |
if (selectorItem == null) { | |
isVirtualizing = true; | |
previousHorizontalOffset = scrollViewer.HorizontalOffset; | |
previousVerticalOffset = scrollViewer.VerticalOffset; | |
// call task-based ScrollIntoViewAsync to realize the item | |
await listViewBase.ScrollIntoViewAsync(listViewBase.Items[index]); | |
// this time the item shouldn't be null again | |
selectorItem = (SelectorItem)listViewBase.ContainerFromIndex(index); | |
} | |
// calculate the position object in order to know how much to scroll to | |
var transform = selectorItem.TransformToVisual((UIElement)scrollViewer.Content); | |
var position = transform.TransformPoint(new Point(0, 0)); | |
// when virtualized, scroll back to previous position without animation | |
if (isVirtualizing) { | |
await scrollViewer.ChangeViewAsync(previousHorizontalOffset, previousVerticalOffset, true); | |
} | |
// scroll to desired position with animation! | |
scrollViewer.ChangeView(position.X, position.Y, null); | |
} | |
public async static Task ScrollToItem(this ListViewBase listViewBase, object item) { | |
bool isVirtualizing = default(bool); | |
double previousHorizontalOffset = default(double), previousVerticalOffset = default(double); | |
// get the ScrollViewer withtin the ListView/GridView | |
//var scrollViewer = listViewBase.GetScrollViewer(); | |
var scrollViewer = listViewBase.GetChildOfType<ScrollViewer>(); | |
// get the SelectorItem to scroll to | |
var selectorItem = listViewBase.ContainerFromItem(item) as SelectorItem; | |
// when it's null, means virtualization is on and the item hasn't been realized yet | |
if (selectorItem == null) { | |
isVirtualizing = true; | |
previousHorizontalOffset = scrollViewer.HorizontalOffset; | |
previousVerticalOffset = scrollViewer.VerticalOffset; | |
// call task-based ScrollIntoViewAsync to realize the item | |
await listViewBase.ScrollIntoViewAsync(item); | |
// this time the item shouldn't be null again | |
selectorItem = (SelectorItem)listViewBase.ContainerFromItem(item); | |
} | |
// calculate the position object in order to know how much to scroll to | |
var transform = selectorItem.TransformToVisual((UIElement)scrollViewer.Content); | |
var position = transform.TransformPoint(new Point(0, 0)); | |
// when virtualized, scroll back to previous position without animation | |
if (isVirtualizing) { | |
await scrollViewer.ChangeViewAsync(previousHorizontalOffset, previousVerticalOffset, true); | |
} | |
// scroll to desired position with animation! | |
scrollViewer.ChangeView(position.X, position.Y, null); | |
} | |
public static async Task ScrollIntoViewAsync(this ListViewBase listViewBase, object item) { | |
var tcs = new TaskCompletionSource<object>(); | |
//var scrollViewer = listViewBase.GetScrollViewer(); | |
var scrollViewer = listViewBase.GetChildOfType<ScrollViewer>(); | |
EventHandler<ScrollViewerViewChangedEventArgs> viewChanged = (s, e) => tcs.TrySetResult(null); | |
try { | |
scrollViewer.ViewChanged += viewChanged; | |
listViewBase.ScrollIntoView(item, ScrollIntoViewAlignment.Leading); | |
await tcs.Task; | |
} | |
finally { | |
scrollViewer.ViewChanged -= viewChanged; | |
} | |
} | |
public static async Task ChangeViewAsync(this ScrollViewer scrollViewer, double? horizontalOffset, double? verticalOffset, bool disableAnimation) { | |
var tcs = new TaskCompletionSource<object>(); | |
EventHandler<ScrollViewerViewChangedEventArgs> viewChanged = (s, e) => tcs.TrySetResult(null); | |
try { | |
scrollViewer.ViewChanged += viewChanged; | |
scrollViewer.ChangeView(horizontalOffset, verticalOffset, null, disableAnimation); | |
await tcs.Task; | |
} | |
finally { | |
scrollViewer.ViewChanged -= viewChanged; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment