none
关于ScrollViewer Zoom RRS feed

  • 问题

  • 大家好:

        我的项目里需要使用一个复杂的控件来显示数据。框架里面没有能满足要求的控件,所以我自己重写了一个虚拟化Panel,将其作为ItemsControl的ItemsPanel。由于需要实现Zoom功能,所以在ItemsControl的外面套了一个ScrollViewer以使用ScrollViewer的自带的Zoom支持。不过,我发现了一个Bug,如下:

          设置ScrollViewer的MaxZoomFactor和MinZoomFactor,当用户Zoom到ZoomFactor超出MaxZoomFactor和MinZoomFactor的范围时,ScrollViewer依然允许继续Zoom一定范围,之后一旦松开,会自动回弹到MaxZoomFactor或MinZoomFactor。问题是,当Zoom超出MaxZoomFactor和MinZoomFactor的范围时,ZoomFactor这个属性就不变化了,我认为这是一个BUG。由于我需要使用ZoomFactor来计算我的自定义虚拟化Panel描画哪些item,一旦ZoomFactor不变了,我的描画就会出问题。我尝试了不使用ScrollViewer提供的ZoomFactor来自己计算,通过ExtentWidth,但是发现ExtentWidth也是一样,一旦Zoom超出MaxZoomFactor和MinZoomFactor的范围时就保持不变了。我很苦恼,检查了所有的ScrollViewer的Width和Height相关的属性,都是不行的。

    请问我该如何在Zoom超出MaxZoomFactor和MinZoomFactor的范围时得到正确的ZoomFactor?

    以下是再现的小Demo的部分代码:

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ScrollViewer x:Name="TestScrollViewer" MaxZoomFactor="2" MinZoomFactor="0.7" ViewChanged="ScrollViewer_ViewChanged">
                <ListBox x:Name="TestListBox" Loaded="TestListBox_Loaded" HorizontalAlignment="Right"/>
            </ScrollViewer>
            
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Background="LightBlue">
                <StackPanel  Orientation="Horizontal">
                    <TextBlock Text="ZoomFactor : " FontSize="16" Foreground="Black"/>
                    <TextBlock x:Name="TestZoomFactor" FontSize="16" Foreground="Black"/>
                </StackPanel>
    
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="ScrollableWidth : " FontSize="16" Foreground="Black"/>
                    <TextBlock x:Name="TestScrollableWidth" FontSize="16" Foreground="Black"/>
                </StackPanel>
    
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="ExtentWidth : " FontSize="16" Foreground="Black"/>
                    <TextBlock x:Name="TestExtentWidth" FontSize="16" Foreground="Black"/>
                </StackPanel>
    
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="ViewportWidth : " FontSize="16" Foreground="Black"/>
                    <TextBlock x:Name="TestViewportWidth" FontSize="16" Foreground="Black"/>
                </StackPanel>
                
            </StackPanel>
        </Grid>

    public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            /// <summary>
            /// Invoked when this page is about to be displayed in a Frame.
            /// </summary>
            /// <param name="e">Event data that describes how this page was reached.  The Parameter
            /// property is typically used to configure the page.</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
    
            private void TestListBox_Loaded(object sender, RoutedEventArgs e)
            {
                for (int i = 0; i < 10; ++i)
                {
                    this.TestListBox.Items.Add(new ListBoxItem() { Content = i.ToString() + "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" });
                }
            }
    
            private void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
            {
                this.TestZoomFactor.Text = this.TestScrollViewer.ZoomFactor.ToString();
                this.TestExtentWidth.Text = this.TestScrollViewer.ExtentWidth.ToString();
                this.TestViewportWidth.Text = this.TestScrollViewer.ViewportWidth.ToString();
                this.TestScrollableWidth.Text = this.TestScrollViewer.ScrollableWidth.ToString();
            }
        }

    我非常着急啊,请大家帮忙!!!

    非常感谢!

    补充一下啊:

    如果能告诉我ScrollViewer的Zoom实现原理(比如是通过改变ScrollViewer的RenderTransform,或者改变ScrollContentPresenter的RenderTransform,不过我看了,好像都不是),我想这个问题是可以解决的,就可以通过监控这些属性来得到其准确的ZoomFactor。

    2013年6月19日 8:07

全部回复