How to scroll to element in UWP
A better solution is to use ChangeView
instead of ScrollToVerticalOffset
/ScrollToHorizontalOffset
since the latter is obsolete in Windows 10.
MyScrollView.ChangeView(null, abosulatePosition.Y, null, true);
You can even enable scrolling animation by setting the last parameter to false
.
Update
For the sake of completion, I've created an extension method for this.
public static void ScrollToElement(this ScrollViewer scrollViewer, UIElement element,
bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null)
{
var transform = element.TransformToVisual((UIElement)scrollViewer.Content);
var position = transform.TransformPoint(new Point(0, 0));
if (isVerticalScrolling)
{
scrollViewer.ChangeView(null, position.Y, zoomFactor, !smoothScrolling);
}
else
{
scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling);
}
}
So in this case, just need to call
this.MyScrollView.ScrollToElement(otherTb);
Scroll to new item in ListView for UWP
As of Windows 10, version 1607 you can use ItemsStackPanel
.ItemsUpdatingScrollMode
with the value KeepLastItemInView
, which seems like the most natural fit for the job.
There is an "Inverted Lists" example in MS UWP docs (2017-2-8) that would boil down to this XAML:
<ListView Source="{Binding Messages}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel
VerticalAlignment="Bottom"
ItemsUpdatingScrollMode="KeepLastItemInView"
/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
On a side note, yes, I'd agree that you may want to get rid of a ScrollViewer
as it's redundant as a ListView
wrapper.
Upd:
KeepLastItemInView
is not available for applications that target Windows 10 prior to the "Anniversary Edition". If that's the case, one way to make sure that a list always displays the last item after item collection is changed is to override OnItemsChanged
and call ScrollIntoView
. A basic implementation would look like this:
using System.Linq;
using Windows.UI.Xaml.Controls;
public class ChatListView : ListView
{
protected override void OnItemsChanged(object e)
{
base.OnItemsChanged(e);
if(Items.Count > 0) ScrollIntoView(Items.Last());
}
}
UWP ScrollViewer not scrolling
Try this. This should work perfectly.
<ScrollViewer Grid.Row="1"
Grid.Column="0"
Height="600"
HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto"
VerticalAlignment="Top">
<!--If the elements don't exceed the size of the box, the scrollbar won't be visible-->
<!--Use your BG color-->
<Border Background="White"
HorizontalAlignment="Stretch" >
<!--Use SPanel or grid or RPanel to include more than one element-->
<StackPanel Margin="10">
<TextBlock x:Name="editor"
TextWrapping="Wrap"
Text="Custom Text more that the screen or the box size"/>
</StackPanel>
</Border>
</ScrollViewer>
MasterDetailView UWP - Access the ListView (or make it scroll)
You can use a FindChildOfType implementation to get the ListView through VisualTreeHelper, as indicated in this answer:
Windows UWP - How to programmatically scroll ListView in ContentTemplate
uwp - scrollviewer doesn't keep scroll position when content is updated
There are two ways I can think of right away that use the ScrollViewer
.
All methods below assume you know the index of the item you want to bring into view. If you don't know this you can use the current scrolllocation or selected item (in case of a
ListView
) to obtain this index.
The first method is by using ScrollViewer.ChangeView()
:
After you have added a new item to StackItems
you can add this line of code:
Scroller.ChangeView(
StackItems.Padding.Left +
StackItems.Children
.Take(indexToBringIntoView)
.Sum(u => u.ActualSize.X),
null,
null
);
If the width of all items are equal you can instead just write of course:
Scroller.ChangeView(StackItems.Padding.Left + itemWidth * indexToBringIntoView, null, null);
The second method is by using UIElement.StartBringIntoView()
:
This method is easier than the first method, however I have noticed some strange behaviour of the
ScrollViewer
when using this.
After adding your new item to the StackItems
you can use the following the bring you previous item into view:
StackItems.Children[indexToBringIntoView].StartBringIntoView();
Another way of achieving your goal is to use a horizontal ListView
You can set this up following the accepted answer from this SO thread.
Then if you have the index of the item you want to bring into view you can use ListView.ScrollIntoView(object item)
like so:
listView.ScrollIntoView(Lister.Items[indexToBringIntoView]);
I have included this method as well since this is a very solid working method and I never had a problem with it.
If this is not what you are looking for, let me know and I'll adjust my answer.
Related Topics
How to Get the Icon from the Executable File Only Having an Instance of It's Process in C#
Set Environment Variables for a Process
Find If Point Lies on Line Segment
Combine Two Linq Lambda Expressions
Wpf Controls Needed to Build Chess Application
Does Foreach Automatically Call Dispose
How to Add Property-Level Attribute to the Typedescriptor at Runtime
How to Make a Console Application Run Using Only a Single File in .Net Core
Return All Enumerables with Yield Return at Once; Without Looping Through
Get Powershell Command's Output When Invoked Through Code
Creating a Circularly Linked List in C#
How to Create a New Operator in C#
Async Always Waitingforactivation
Outofmemoryexception on Declaration of Large Array