更改 Tab 时防止 TabItem 中的 ScrollViewer 重置偏移量

Prevent ScrollViewer in TabItem reset offset when changing Tab

我有这个代码:

<TabItem Header="Card Details">
    <ScrollViewer Name="cardDetailsScroll" MaxHeight="600" Width="Auto" Padding="10">
        <StackPanel>
            <Canvas Height="50">
            </Canvas>
            ...
        </StackPanel>
    </ScrollViewer>
</TabItem>

每次我更改 Tab 然后返回时,ScrollViewer 都会重置其偏移量(到顶部)。使用 StackPanel 时我错了吗?还是我错过了什么?

谢谢。

这是 WPF 的预期行为,您可以从 THIS thread. If you use MVVM you could bind the offset postion of the scroll viewer using an attached behavior suggested HERE 中了解到,或者如果您更喜欢自定义选项卡控件,前者 link 包含一个很好的起点。

来自 Daniel Leiszen 的第一个 link:

The default behavior of WPF is to unload items which are not visible, which includes unloading TabItems which are not visible. This means when you go back to the tab, the TabItem gets re-loaded, and anything not bound (such as a scroll position) will get reset.

在我问之前我已经想到了这个解决方案, 我只是想知道一些其他的解决方案来帮助我增长知识:

private void cardDetailsScroll_Loaded(object sender, RoutedEventArgs e)
{
    double offset;
    if (cardDetailsScroll.Tag != null 
         && double.TryParse(cardDetailsScroll.Tag.ToString(), out offset))
    {
        cardDetailsScroll.ScrollToVerticalOffset(offset);                
    }
}

private void cardDetailsScroll_Unloaded(object sender, RoutedEventArgs e)
{
    cardDetailsScroll.Tag = cardDetailsScroll.VerticalOffset;
}

我在使用 TabControl 时遇到了类似的问题。每个选项卡都显示来自 UserControl 的图形,当我在选项卡之间切换时,滚动查看器在激活选项卡后滚动回原点。

我使用了与 Onfealive 提议的类似方法。但是我使用了 Horizo​​ntalOffset 和 VerticalOffset 而不是 Tag。

    private void m_ScrollViewer_Loaded(object sender, RoutedEventArgs e)
    {
        m_ScrollViewer.ScrollToHorizontalOffset(m_HorizontalOffset);
        m_ScrollViewer.ScrollToVerticalOffset(m_VerticalOffset);
    }

    private void m_ScrollViewer_Unloaded(object sender, RoutedEventArgs e)
    {
        m_HorizontalOffset = m_ScrollViewer.HorizontalOffset;
        m_VerticalOffset = m_ScrollViewer.VerticalOffset;
    }

这对我有用,我认为这种方法更安全!