2014-01-08 2 views
5

В моем приложении Windows Phone у меня есть два LongListSelectors бок о бок на странице. Я хотел бы сделать так, чтобы, когда пользователь прокручивает один из них, другой прокручивает ту же сумму.Положение прокрутки/галстука с двумя длинными листами.

У двух LongListSelectors есть ItemTemplates, которые всегда будут иметь одинаковые высоты. Вы можете подумать об этом, как имитировать замороженные столбцы в Excel (левый LongListSelector только прокручивает по вертикали, правый прокручивает по горизонтали и по вертикали.

Может ли кто-нибудь указать мне в правильном направлении, как это сделать? желая сделать это в кодировке или что-то еще, если это невозможно сделать с привязкой.

ответ

3

Вы можете сделать это, зацепив в ViewportControl в LongListSelector. Когда область просмотра одного LLS изменится, измените Viewport другого LLS. Я предполагаю, что вам нужно только два LLS, поэтому один DependencyProperty должен сделать трюк. Я написал a blog со всеми подробностями о том, как это сделать.

Суть этого является необходимость в 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)); 

И установить свойство при изменении Viewport.

private void OnViewportChanged(object sender, ViewportChangedEventArgs args) 
{ 
    ScrollPosition = _viewport.Viewport.Top; 
} 

Затем связать свойство каждого LLS в вашем 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}"/> 
+0

Отличная реализация! – Depechie

+0

@Shawn Kendrot - Большое спасибо за эту реализацию. Я использовал его и заработал около 95% пути. Вероятно, это достаточно хорошо, но у меня есть одно наблюдение - есть ли способ сделать «отказов» и «растянуть» синхронизацию между ними? Если вы проложите весь путь до вершины одного, он будет идти немного дальше, чем нужно, но другой не будет. Вы можете увидеть его в клипе Youtube прямо в конце.Это не самая большая проблема в мире, но, поскольку ваш ответ был настолько спонтанным, я подумал, что посмотрю, сможешь ли вы это решить. – Tim

+0

Дайте мыши печенье, да? Geez! (просто шучу). Я посмотрю, есть ли способ решить это, возможно, в выходные. –

3

Хотя я никогда не разрабатывал для Windows Phone, я очень хорошо знаком с XAML из WPF и имел похожие проблемы, мне нужно было синхронизировать ширину полос на нескольких гистограммах.Мое предлагаемое решение использует свойства зависимостей, чтобы вы могли связывать свои ListSelectors в XAML, как с SharedSizeGroup в сетках. Если вы не знакомы с Свойствами зависимостей, начните с поиска here. Поскольку у меня нет доступа к запрограммированным сборкам для Windows Phone, это не было протестировано, но оно работает в очень похожих сценариях.

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; Я нашел строку использовать в link вы предоставили.

Вам может понадобиться, чтобы добавить что-то, если установка scrollBar.Value поднимает OnScroll -Event, так что вы не получите переполнение стека :)

Также добавление элементов управления в Grouping -dictionary осталось как execise к читателю , это должно быть довольно легко. Если вы сами создаете собственные элементы управления, попробуйте this ресурс для начинающих.

Чтобы использовать ваш готовый контроль просто добавить его в XAML следующим образом: <yourNamespace:SyncedLongListSelector GroupName="MySyncedGroup" />

+0

Благодаря @Zache - я дам этому маршруту выстрел сегодня, и пусть вы знаете, мои результаты. Очень признателен! – Tim

+0

Жаль, что я не мог отдать вам часть щедрости, так как ваше решение было очень близко к тому, что мне было нужно, Шон был чуть более полным. Хотя, конечно же, вы дали вам преимущество! Еще раз спасибо! – Tim

Смежные вопросы