Синхронизация смещений между двумя ScrollViewer без кода программной части

Прямо сейчас у меня есть два средства просмотра прокрутки, которым нужно всегда иметь одинаковое смещение.

(Рабочее) решение, которое у меня есть прямо сейчас, связано с событием ScrollChanged. Если событие ScrollChanged запускается, этот код выполняется:

scrollViewer.ScrollToHorizontalOffset(offset.X);
scrollViewer.ScrollToVerticalOffset(offset.Y);

Дело в том, что я хочу попытаться избежать этого решения с кодом программной части.

Я думаю, что лучшим решением этой проблемы является что-то вроде этого (привязка):

 <ScrollViewer x:Name="scrollviewer_Top" HorizontalOffset="{Binding ElementName=scrollViewer_Center, Path=HorizontalOffset}">...</ScrollViewer>

 <ScrollViewer x:Name="scrollViewer_Left" VerticalOffset="{Binding ElementName=scrollViewer_Center, Path=VerticalOffset}" >...</ScrollViewer>

 <ScrollViewer x:Name="scrollViewer_Center" HorizontalOffset="{Binding ElementName=scrollviewer_Top, Path=HorizontalOffset}"
                                  VerticalOffset="{Binding ElementName=scrollViewer_Left, Path=VerticalOffset}">...</ScrollViewer>

Теперь, когда я пытаюсь построить, я получаю несколько ошибок (HorizontalOffset/VerticalOffset не может быть установлен, потому что у него нет доступного набора доступа).

Кто-нибудь знает, является ли это лучшим решением и как справиться с ошибкой? Или я должен остаться с событием кода программной части?

Спасибо


person Kjell Derous    schedule 10.01.2014    source источник
comment
В этом случае использование кода позади, вероятно, является самым простым решением, поэтому я бы придерживался его. Это также приемлемо, если вы используете MVVM, так как это полностью логика представления.   -  person Adi Lester    schedule 10.01.2014
comment
@Ади Лестер. Да, я буду придерживаться кода позади. Кажется, другого решения нет.   -  person Kjell Derous    schedule 10.01.2014
comment
Я только что отредактировал ваш заголовок, потому что ранее он был несколько субъективным и мог привести к тому, что ваш вопрос был удален сообществом.   -  person Sheridan    schedule 10.01.2014


Ответы (1)


Хотя в этой ситуации нет ничего плохого в использовании кода позади, часто принято инкапсулировать обработку событий в прикрепленные свойства при использовании WPF с MVVM. Итак, если вы действительно хотите избавиться от кода, вы можете сделать это. См. обзор присоединенных свойств. страницу на MSDN для подробного описания вложенных свойств.

В вашем случае вы можете сделать что-то вроде этого:

public static readonly DependencyProperty LinkedScrollViewerProperty = DependencyProperty.RegisterAttached("LinkedScrollViewer", typeof(ScrollViewer), typeof(ScrollViewerProperties), new UIPropertyMetadata(null, OnLinkedScrollViewerChanged));

public static ScrollViewer GetLinkedScrollViewer(DependencyObject dependencyObject)
{
    return (ScrollViewer)dependencyObject.GetValue(LinkedScrollViewerProperty);
}

public static void SetLinkedScrollViewer(DependencyObject dependencyObject, ScrollViewer value)
{
    dependencyObject.SetValue(LinkedScrollViewerProperty, value);
}

public static void OnLinkedScrollViewerChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    ScrollViewer scrollViewer = (ScrollViewer)dependencyObject;
    ScrollViewer newLinkedScrollViewer = e.NewValue as ScrollViewer;
    if (newLinkedScrollViewer != null)
    {
        newLinkedScrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset);
        newLinkedScrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset);
    }
}

Если бы это было в классе с именем ScrollViewerProperties с префиксом пространства имен Xml Attached, вы могли бы использовать его следующим образом:

<ScrollViewer Name="ScrollViewerToLinkWith" ... />
...
<ScrollViewer Attached:ScrollViewerProperties.LinkedScrollViewer="{Binding 
    ElementName=ScrollViewerToLinkWith}" ... />

Сейчас я не могу это проверить, так что вам, возможно, придется это настроить, но выглядит примерно так. Кроме того, вы можете обрабатывать практически любое событие пользовательского интерфейса, подобное этому.

person Sheridan    schedule 10.01.2014