网格 WPF 上多个 DataGrid 的单个滚动条
Single scrollbar for multiple DataGrids on a grid WPF
我在网格上有两个 DataGrid,其中一个 DataGrid 恰好放在另一个的下方,这两个 DataGrid 共享同一列 headers 我想做的是我想使用单个滚动条(水平滚动条)用于这两个 DataGrids 。我该怎么做??
<Grid>
<DataGrid Name="StatusGrid"
Height="Auto"
Width="Auto"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserReorderColumns="False" />
<DataGrid AutoGenerateColumns="False"
Height="auto"
Width="auto"
Margin="0,73,0,10"
Name="heatMap"
IsReadOnly="True"
CanUserReorderColumns="False"
CanUserSortColumns="False"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ItemsSource="{Binding HeatMapCollection}"
Background="AliceBlue" />
</Grid>
你可以这样使用ScrollViewer
。
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0">
<DataGrid.Columns>
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
</DataGrid.Columns>
</DataGrid>
<DataGrid Grid.Row="1">
<DataGrid.Columns>
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</ScrollViewer>
像
一样尝试使用 ScrollViewer
<ScrollViewer CanContentScroll="True"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0"
Name="StatusGrid"
Height="Auto"
Width="Auto"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserReorderColumns="False" />
<DataGrid Grid.Row="1"
AutoGenerateColumns="False"
Width="1000"
Margin="0,73,0,10"
Name="heatMap"
IsReadOnly="True"
CanUserReorderColumns="False"
CanUserSortColumns="False"
ItemsSource="{Binding HeatMapCollection}"
Background="AliceBlue" />
</Grid>
</ScrollViewer>
我正在使用以下附件-属性 来同步它们。 (不确定我从哪里得到的)
public class ScrollSynchronizer : DependencyObject
{
public static readonly DependencyProperty ScrollGroupProperty =
DependencyProperty.RegisterAttached(
"ScrollGroup",
typeof (string),
typeof (ScrollSynchronizer),
new PropertyMetadata(OnScrollGroupChanged));
private static readonly Dictionary<ScrollViewer, string> scrollViewers = new Dictionary<ScrollViewer, string>();
private static readonly Dictionary<string, double> horizontalScrollOffsets = new Dictionary<string, double>();
private static readonly Dictionary<string, double> verticalScrollOffsets = new Dictionary<string, double>();
private static void OnScrollGroupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ScrollViewer scrollViewer = d as ScrollViewer;
if (scrollViewer != null)
{
if (!string.IsNullOrEmpty((string) e.OldValue))
{
if (scrollViewers.ContainsKey(scrollViewer))
{
scrollViewer.ScrollChanged -= ScrollViewerScrollChanged;
}
}
if (!string.IsNullOrEmpty((string) e.NewValue))
{
if (horizontalScrollOffsets.ContainsKey((string) e.NewValue))
{
scrollViewer.ScrollToHorizontalOffset(horizontalScrollOffsets[(string) e.NewValue]);
}
else
{
horizontalScrollOffsets.Add((string) e.NewValue, scrollViewer.HorizontalOffset);
}
if (verticalScrollOffsets.ContainsKey((string) e.NewValue))
{
scrollViewer.ScrollToVerticalOffset(verticalScrollOffsets[(string) e.NewValue]);
}
else
{
verticalScrollOffsets.Add((string) e.NewValue, scrollViewer.VerticalOffset);
}
scrollViewers.Add(scrollViewer, (string) e.NewValue);
scrollViewer.ScrollChanged += ScrollViewerScrollChanged;
}
}
}
private static void ScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (e.VerticalChange != 0 || e.HorizontalChange != 0)
{
ScrollViewer changedScrollViewer = sender as ScrollViewer;
Scroll(changedScrollViewer);
}
}
private static void Scroll(ScrollViewer changedScrollViewer)
{
string group = scrollViewers[changedScrollViewer];
verticalScrollOffsets[group] = changedScrollViewer.VerticalOffset;
horizontalScrollOffsets[group] = changedScrollViewer.HorizontalOffset;
foreach (
KeyValuePair<ScrollViewer, string> scrollViewer in
scrollViewers.Where(s => s.Value == group && s.Key != changedScrollViewer))
{
if (scrollViewer.Key.VerticalOffset != changedScrollViewer.VerticalOffset)
{
scrollViewer.Key.ScrollToVerticalOffset(changedScrollViewer.VerticalOffset);
}
if (scrollViewer.Key.HorizontalOffset != changedScrollViewer.HorizontalOffset)
{
scrollViewer.Key.ScrollToHorizontalOffset(changedScrollViewer.HorizontalOffset);
}
}
}
public static void SetScrollGroup(DependencyObject element, string value)
{
element.SetValue(ScrollGroupProperty, value);
}
public static string GetScrollGroup(DependencyObject element)
{
return (string) element.GetValue(ScrollGroupProperty);
}
}
而您的 DataGrid-Definitions 中的用法您必须这样写:
nameSpaceOfAttachedProperty:ScrollSynchronizer.ScrollGroup="MyScrollGroup"
使用此代码,您可以在任何地方同步滚动。
我在网格上有两个 DataGrid,其中一个 DataGrid 恰好放在另一个的下方,这两个 DataGrid 共享同一列 headers 我想做的是我想使用单个滚动条(水平滚动条)用于这两个 DataGrids 。我该怎么做??
<Grid>
<DataGrid Name="StatusGrid"
Height="Auto"
Width="Auto"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserReorderColumns="False" />
<DataGrid AutoGenerateColumns="False"
Height="auto"
Width="auto"
Margin="0,73,0,10"
Name="heatMap"
IsReadOnly="True"
CanUserReorderColumns="False"
CanUserSortColumns="False"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ItemsSource="{Binding HeatMapCollection}"
Background="AliceBlue" />
</Grid>
你可以这样使用ScrollViewer
。
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0">
<DataGrid.Columns>
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
</DataGrid.Columns>
</DataGrid>
<DataGrid Grid.Row="1">
<DataGrid.Columns>
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
<DataGridTextColumn Width="200" Header="test" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</ScrollViewer>
像
一样尝试使用 ScrollViewer<ScrollViewer CanContentScroll="True"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0"
Name="StatusGrid"
Height="Auto"
Width="Auto"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserReorderColumns="False" />
<DataGrid Grid.Row="1"
AutoGenerateColumns="False"
Width="1000"
Margin="0,73,0,10"
Name="heatMap"
IsReadOnly="True"
CanUserReorderColumns="False"
CanUserSortColumns="False"
ItemsSource="{Binding HeatMapCollection}"
Background="AliceBlue" />
</Grid>
</ScrollViewer>
我正在使用以下附件-属性 来同步它们。 (不确定我从哪里得到的)
public class ScrollSynchronizer : DependencyObject
{
public static readonly DependencyProperty ScrollGroupProperty =
DependencyProperty.RegisterAttached(
"ScrollGroup",
typeof (string),
typeof (ScrollSynchronizer),
new PropertyMetadata(OnScrollGroupChanged));
private static readonly Dictionary<ScrollViewer, string> scrollViewers = new Dictionary<ScrollViewer, string>();
private static readonly Dictionary<string, double> horizontalScrollOffsets = new Dictionary<string, double>();
private static readonly Dictionary<string, double> verticalScrollOffsets = new Dictionary<string, double>();
private static void OnScrollGroupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ScrollViewer scrollViewer = d as ScrollViewer;
if (scrollViewer != null)
{
if (!string.IsNullOrEmpty((string) e.OldValue))
{
if (scrollViewers.ContainsKey(scrollViewer))
{
scrollViewer.ScrollChanged -= ScrollViewerScrollChanged;
}
}
if (!string.IsNullOrEmpty((string) e.NewValue))
{
if (horizontalScrollOffsets.ContainsKey((string) e.NewValue))
{
scrollViewer.ScrollToHorizontalOffset(horizontalScrollOffsets[(string) e.NewValue]);
}
else
{
horizontalScrollOffsets.Add((string) e.NewValue, scrollViewer.HorizontalOffset);
}
if (verticalScrollOffsets.ContainsKey((string) e.NewValue))
{
scrollViewer.ScrollToVerticalOffset(verticalScrollOffsets[(string) e.NewValue]);
}
else
{
verticalScrollOffsets.Add((string) e.NewValue, scrollViewer.VerticalOffset);
}
scrollViewers.Add(scrollViewer, (string) e.NewValue);
scrollViewer.ScrollChanged += ScrollViewerScrollChanged;
}
}
}
private static void ScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (e.VerticalChange != 0 || e.HorizontalChange != 0)
{
ScrollViewer changedScrollViewer = sender as ScrollViewer;
Scroll(changedScrollViewer);
}
}
private static void Scroll(ScrollViewer changedScrollViewer)
{
string group = scrollViewers[changedScrollViewer];
verticalScrollOffsets[group] = changedScrollViewer.VerticalOffset;
horizontalScrollOffsets[group] = changedScrollViewer.HorizontalOffset;
foreach (
KeyValuePair<ScrollViewer, string> scrollViewer in
scrollViewers.Where(s => s.Value == group && s.Key != changedScrollViewer))
{
if (scrollViewer.Key.VerticalOffset != changedScrollViewer.VerticalOffset)
{
scrollViewer.Key.ScrollToVerticalOffset(changedScrollViewer.VerticalOffset);
}
if (scrollViewer.Key.HorizontalOffset != changedScrollViewer.HorizontalOffset)
{
scrollViewer.Key.ScrollToHorizontalOffset(changedScrollViewer.HorizontalOffset);
}
}
}
public static void SetScrollGroup(DependencyObject element, string value)
{
element.SetValue(ScrollGroupProperty, value);
}
public static string GetScrollGroup(DependencyObject element)
{
return (string) element.GetValue(ScrollGroupProperty);
}
}
而您的 DataGrid-Definitions 中的用法您必须这样写:
nameSpaceOfAttachedProperty:ScrollSynchronizer.ScrollGroup="MyScrollGroup"
使用此代码,您可以在任何地方同步滚动。