我有以下代码:
<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>
滚动条的行为是多么奇怪 - 如果我向下滚动第一个选项卡并切换到第二个选项卡,滚动条也会关闭 - 当选项卡项具有相同的数据模板时,滚动条的位置会同步。你知道这个问题的任何解决方案吗?
此外,当我更改代码并制作两个数据模板(每个选项卡一个)时,滚动条根本不保留它们的位置 - 这意味着如果我向下滚动tab1,再次切换到tab2和tab1,滚动条位于默认位置。这个的任何解决方案?
答案 0 :(得分:3)
要让DataTemplate
为每次使用创建单独的实例,只需将x:Shared
属性设置为False
:
<DataTemplate x:Key="tabTemplate" x:Shared="False">
这将导致您的第二个问题,即在选项卡更改时保留UI。根据{{3}},解决方案是使用看起来像ItemsControl
的其他TabControl
。
答案 1 :(得分:1)
我使用新控件ZoomPanel : ScrollViewer
解决了第二个问题,其中根据DataContext.GetHashCode()
保存了scollbar的位置。也许不是最佳解决方案,但对我有用。每个选项卡都有自己的ViewModel,因此保留滚动条的位置。
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);
}
}