Reputation: 727
I have following code:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="145" Width="156">
<Window.Resources>
<DataTemplate x:Key="tabTemplate">
<ScrollViewer>
<StackPanel Orientation="Vertical">
<TextBlock>x</TextBlock>
<TextBlock>x</TextBlock>
<TextBlock>x</TextBlock>
<TextBlock>x</TextBlock>
<TextBlock>x</TextBlock>
<TextBlock>x</TextBlock>
<TextBlock>x</TextBlock>
</StackPanel>
</ScrollViewer>
</DataTemplate>
</Window.Resources>
<Grid>
<TabControl>
<TabItem Header="Tab1" ContentTemplate="{StaticResource ResourceKey=tabTemplate}"/>
<TabItem Header="Tab2" ContentTemplate="{StaticResource ResourceKey=tabTemplate}"/>
</TabControl>
</Grid>
</Window>
What is weird is the behavior of scrollbars - if I scroll down on the first tab and switch to second tab, the scrollbar is down too - position of the scrollbars is synchronized when the tab items have the same data templates. Do you know about any solution of this issue?
In addition, when I alter the code and make two data templates (one for each tab), the scrollbars are not preserving their position at all - that means if I scroll down on tab1, switch to tab2 and to tab1 again, the scrollbar is on default position. Any solution of this one?
Upvotes: 1
Views: 1927
Reputation: 727
I solved the second issue using new control ZoomPanel : ScrollViewer
, where the position of scollbars is saved according to DataContext.GetHashCode()
. Maybe not optimal solution, but works for me. Every tab has its own ViewModel, so the position of scrollbars is preserved.
public static readonly Dictionary<int, Point> ScrollbarPositions = new Dictionary<int, Point>();
private void ZoomPanelScrollChanged(object sender, ScrollChangedEventArgs e)
{
ZoomPanel panel = (ZoomPanel)sender;
// do not save position when uloading or empty data context
if(!panel.IsLoaded || this.DataContext == null)
{
return;
}
// save scrollbar position
int dataContextHashCode = this.DataContext.GetHashCode();
Point position = new Point(panel.HorizontalOffset, panel.VerticalOffset);
if(ScrollbarPositions.ContainsKey(dataContextHashCode))
{
ScrollbarPositions[dataContextHashCode] = position;
}
else
{
ScrollbarPositions.Add(dataContextHashCode, position);
}
}
private void ZoomPanelLoaded(object sender, RoutedEventArgs e)
{
if(this.DataContext == null)
{
return;
}
// load scrollbar position
int dataContextHashCode = this.DataContext.GetHashCode();
if (ScrollbarPositions.ContainsKey(dataContextHashCode))
{
Point position = ScrollbarPositions[dataContextHashCode];
this.ScrollToHorizontalOffset(position.X);
this.ScrollToVerticalOffset(position.Y);
}
}
Upvotes: 1
Reputation: 1796
To enable the DataTemplate
to create separate instances for each usage, just set the x:Shared
attribute to False
:
<DataTemplate x:Key="tabTemplate" x:Shared="False">
That will cause your second issue, which is preserving the UI when the tab changes. According to WPF UI persistence in TabControl, the solution would be to use a different ItemsControl
that looks like a TabControl
.
Upvotes: 3