【问题标题】:Silverlight DataGrid scrollbar synchronizationSilverlight DataGrid 滚动条同步
【发布时间】:2011-05-11 11:56:30
【问题描述】:
我有 2 个 Silverlight DataGrid,一个在另一个之上。我想同步他们的水平滚动条。
我试图将它们都放在单独的滚动查看器中,并将源滚动查看器的水平偏移设置为目标滚动查看器的水平偏移,但这不起作用,下面的 DataGrid 滚动查看器消失了。我认为这可能是因为这些 Datagrid 在 StackPanel 内?
我还尝试将这两个网格放在第三个网格中并在其上应用滚动查看器,但这也不起作用
有人知道如何解决这个问题吗?
提前非常感谢
【问题讨论】:
标签:
datagrid
silverlight-3.0
scrollviewer
【解决方案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 并找到 in this question 的 Descendants() 方法。