Синхронизация полосы прокрутки Silverlight DataGrid

У меня есть 2 Silverlight DataGrids один поверх другого. Я хочу синхронизировать их горизонтальные полосы прокрутки. Я попытался поместить их оба в отдельные средства просмотра прокрутки и установить горизонтальное смещение исходного средства просмотра прокрутки на горизонтальное смещение целевого средства просмотра прокрутки, но это не работает, приведенное ниже средство просмотра прокрутки DataGrid разочаровывает. Я думаю, это может быть потому, что эти датагриды находятся внутри StackPanel? Я также попытался поместить эти 2 сетки в третью сетку и применить к ней scrollviewer, но это тоже не работает.

Есть ли у кого-нибудь идеи, как это сделать? Заранее большое спасибо


person Madhura    schedule 11.05.2011    source источник


Ответы (1)


Я сделал это в SL4, не знаю, работает ли это в SL3, извините. В документации указано, что API есть, но я его не пробовал.

Уловка заключается в использовании сверстников автоматизации. Получите одноранговые узлы автоматизации шаблона прокрутки для обеих сеток. Когда прокрутка происходит в одной сетке, прокручивайте другую через узел автоматизации.

Чтобы сделать это более конкретным, предположим, что у нас есть 2 сетки с именами _dgGrowth и _dgTotals:

using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

    public partial class MyPageWithGrids : Page {
...
        private ScrollBar _sbGrowth, _sbTotals;
        private AutomationPeer _peerGrowth, _peerTotals;
        private bool _ignoreScrollEvents;

        private void OnPageLoaded(object sender, RoutedEventArgs e) {

            _sbGrowth = GetHorizontalScrollBar(_dgGrowth);
            if (_sbGrowth != null) {
                _sbGrowth.Scroll += OnScrollGrowthGrid;
            }
            _sbTotals = GetHorizontalScrollBar(_dgTotals);
            if (_sbTotals != null) {
                _sbTotals.Scroll += OnScrollTotalsGrid;
            }

            _peerGrowth = FrameworkElementAutomationPeer.CreatePeerForElement(_dgGrowth);
            _peerTotals = FrameworkElementAutomationPeer.CreatePeerForElement(_dgTotals);
        }

        private ScrollBar GetHorizontalScrollBar(DataGrid parentGrid) {
            return parentGrid.Descendents().OfType<ScrollBar>().FirstOrDefault(sb => sb.Name == "HorizontalScrollbar");
        }

        private void OnScrollTotalsGrid(object sender, ScrollEventArgs e) {

            if (! _ignoreScrollEvents) {
                SyncHorizontalScroll(_peerTotals, _peerGrowth);
            }
        }

        private void OnScrollGrowthGrid(object sender, ScrollEventArgs e) {

            if (! _ignoreScrollEvents) {
                SyncHorizontalScroll(_peerGrowth, _peerTotals);
            }
        }

        private void SyncHorizontalScroll(AutomationPeer source, AutomationPeer copy) {

            IScrollProvider sourceProvider = null;
            if (source != null) {
                sourceProvider = (IScrollProvider) source.GetPattern(PatternInterface.Scroll);
            }
            IScrollProvider copyProvider = null;
            if (copy != null) {
                copyProvider = (IScrollProvider) copy.GetPattern(PatternInterface.Scroll);
            }

            if (sourceProvider != null && copyProvider != null) {

                _ignoreScrollEvents = true;

                // scroll copy at horizontal position of source, and keep vertical position
                copyProvider.SetScrollPercent(sourceProvider.HorizontalScrollPercent, copyProvider.VerticalScrollPercent);

                _ignoreScrollEvents = false;
            }
        }
    }

Что не показано, так это настройка события Loaded для OnPageLoaded и метода Descendants (), найденного в этот вопрос.

person Timores    schedule 25.08.2011