One of our applications contains a UserControl where we have multiple layers of ItemsControls that are kept in sync when scrolling. The ItemsControl is virtualized. The application is targetting .Net 4.0, not 4.5 and the control works fine on systems that have .Net Framework 4.0 installed. However we now have a pc with .Net Framework 4.5 installed also and it seems it is not 100 % backward compatible (or there is another issue with the system).
What happens is that where in 4.0 any scrolling (mouse wheel / arrows, moving scroll bar) sets the ExtentHeight of the ScrollChanged event to an integer value (seeing as it is virtualized and CanContentScroll is true), while running the same 4.0 application on a system with 4.5 installed, it seems it sets the value to decimal values when moving the scrollbar by clicking it and holding the mouse.
We have reproduced it with this small test Window that is a subset of our control. Running it on a PC with only .Net 4.0 shows only integer values in the MesasgeBox while on a PC with .net 4.5 installed, it also shows decimal values.
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new int[1000];
for (int i = 0; i < 1000; i++)
{
(this.DataContext as int[])[i] = i;
}
}
private void ScrollViewer_ScrollChanged_1(object sender, System.Windows.Controls.ScrollChangedEventArgs e)
{
MessageBox.Show(string.Empty + e.VerticalOffset);
}
}
MainWindow.xaml:
<Grid>
<ItemsControl
VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True"
ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="Orange" BorderBrush="LightGray" BorderThickness="1" Height="50">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<Grid>
<ScrollViewer x:Name="TimelineScrollViewer" Padding="{TemplateBinding Control.Padding}" Focusable="False" Grid.ColumnSpan="2" Grid.RowSpan="2"
ScrollChanged="ScrollViewer_ScrollChanged_1">
<ScrollViewer.Style>
<Style TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="VerticalScrollBarVisibility" Value="Visible" />
</Style>
</ScrollViewer.Style>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" x:Name="TimelineItemsPresenter" />
</ScrollViewer>
</Grid>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</Grid>
Is this a bug or is this documented somewhere? Is it an issue of backward compatibility of .Net 4.5 or actually not related to 4.5 at all and some system configuration instead?
The problem is that the actual visible extent (it still scrolls content like it should) is not equal to the value of the extent and as such, the other layers are not kept exactly in sync anymore in our application. We've created a workaround, but still we didn't expect this.