In my Windows Phone app, I've got two LongListSelectors
side-by-side on a page. I would like to make it so that when the user scrolls one of them, the other one scrolls the same amount.
The two LongListSelectors
have ItemTemplates that will always be of identical heights. You can kind of think of this as mimicking frozen columns in Excel (the left LongListSelector
only scrolls vertically, the right one scrolls horizontally and vertically.
Can anyone point me in the right direction on how to do this? I'm willing to do it in code-behind or whatever if it can't be done with binding.
You can accomplish this by hooking into the ViewportControl of the LongListSelector. When the viewport of one LLS changes, change the Viewport of the other LLS. I'm guessing you only need two LLS, so a single DependencyProperty should do the trick. I wrote up a blog with all of the details on how to accomplish this.
The short of it is the need for a DependencyProperty
public double ScrollPosition
{
get { return (double)GetValue(ViewPortProperty); }
set { SetValue(ViewPortProperty, value); }
}
public static readonly DependencyProperty ViewPortProperty = DependencyProperty.Register(
"ScrollPosition",
typeof(double),
typeof(MyLongListSelector),
new PropertyMetadata(0d, OnViewPortChanged));
And set the property when the Viewport changes.
private void OnViewportChanged(object sender, ViewportChangedEventArgs args)
{
ScrollPosition = _viewport.Viewport.Top;
}
Then bind the property to each LLS in your xaml
<dataBoundApp1:MyLongListSelector x:Name="MainLongListSelector" ItemsSource="{Binding Items}"
ScrollPosition="{Binding ScrollPosition, ElementName=MainLongListSelector2, Mode=TwoWay}"/>
<dataBoundApp1:MyLongListSelector x:Name="MainLongListSelector2" ItemsSource="{Binding Items}" Grid.Column="1"
ScrollPosition="{Binding ScrollPosition, ElementName=MainLongListSelector, Mode=TwoWay}"/>
While I've never developed for Windows Phone I'm very familiar with XAML from WPF and have had similiar problems where I've needed to sync the width of bars across several bar charts. My proposed solution uses Dependency Properties to allow you to bind your ListSelectors in XAML like with the SharedSizeGroup
in Grids. If you're not familiar with Dependency Properties start by looking here. Since I don't have acces to the requiered assemblies for Windows Phone this hasn't been tested but it does work in very similiar scenarios.
public class SyncedLongListSelector : LongListSelector
{
private ScrollBar scrollBar;
private static readonly Dictionary<string, List<SyncedLongListSelector>> Groupings = new Dictionary<string, List<SyncedLongListSelector>>();
public static readonly DependencyProperty GroupNameProperty =
DependencyProperty.Register("GroupName", typeof(string), typeof(SyncedLongListSelector), new PropertyMetadata(default(string)));
public string GroupName
{
get
{
return (string)GetValue(GroupNameProperty);
}
set
{
SetValue(GroupNameProperty, value);
}
}
public override void OnApplyTemplate()
{
scrollBar = GetTemplateChild("VerticalScrollBar") as ScrollBar; // See my comments
if (scrollBar != null)
scrollBar.Scroll += OnScroll;
base.OnApplyTemplate();
}
private void UpdateScrolPosition(double scrollBarValue)
{
scrollBar.Value = scrollBarValue;
}
private void OnScroll(object sender, ScrollEventArgs args)
{
foreach (var otherList in Groupings[GroupName].Where(l => !Equals(l, this)))
otherList.UpdateScrolPosition(scrollBar.Value);
}
}
scrollBar = GetTemplateChild("VerticalScrollBar") as ScrollBar;
I found the string to use in the link you provided.
You might need to add something if setting scrollBar.Value
raises the OnScroll
-event so you don't get a stack overflow :)
Also adding the controls to the Grouping
-dictionary is left as an execise to the reader, it should be quite easy. If making your own controls is new to you try this resource for starters.
To use your ready control simply add it in XAML like so: <yourNamespace:SyncedLongListSelector GroupName="MySyncedGroup" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With