Синхронизация полосы прокрутки Silverlight DataGrid - PullRequest
0 голосов
/ 11 мая 2011

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

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

1 Ответ

1 голос
/ 25 августа 2011

Я сделал это в 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 (), найденный в этом вопросе .

...