可滚动画布,ScrollViewer中包含可移动项目

时间:2013-08-26 14:35:30

标签: c# .net wpf canvas windows-phone-8

我有一个包含Canvas的ScrollViewer。这个Canvas有一些可移动的UIElements。这是我的XAML代码:

<ScrollViewer x:Name="Scroller" HorizontalScrollBarVisibility="Auto" Background="White">
       <Canvas x:Name="MapCanvas" Width="4000" Height="4000">    
                    <Button x:Name="TestBtn" 
                            Content="My button"
                            Canvas.Left="250"
                            ManipulationStarted="MapItem_ManipulationStarted"   
                            ManipulationDelta="MapItem_ManipulationDelta" 
                            ManipulationCompleted="MapItem_ManipulationCompleted"   
                            />                                  
      </Canvas>
</ScrollViewer>

以下是事件处理程序的代码:

private void MapItem_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
        {
            FrameworkElement btn = sender as FrameworkElement;
            if (null == btn) return;            

            double left = Canvas.GetLeft(btn) + e.DeltaManipulation.Translation.X;
            double top = Canvas.GetTop(btn) + e.DeltaManipulation.Translation.Y;

            if (left < 0)
                left = 0;
            else if (left >  MapCanvas.ActualWidth - btn.ActualWidth)
                left = MapCanvas.ActualWidth - btn.ActualWidth;

            if (top < 0)
                top = 0;
            else if(top > MapCanvas.ActualHeight - btn.ActualHeight)
                top = MapCanvas.ActualHeight - btn.ActualHeight;

            Canvas.SetLeft(btn, left);
            Canvas.SetTop(btn, top);

            e.Handled = true;
        }

        private void MapItem_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
        {
            Scroller.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
            Scroller.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;            

            e.Handled = true;
        }

        private void MapItem_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
        {
            Scroller.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
            Scroller.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;

            e.Handled = true;
        }

一切都很完美。但是当ScrollViewer滚动到某个Horizo​​ntalOffset或VerticalOffset并且我点击或点击可见区域中的任何UIElement时,似乎ScrollViewer会自动滚动到HorisontalOffset == 0和VerticalOffset == 0.然后,在释放UIElement后,它会跳回。 我怎样才能避免这种行为,让ScrollViewer留在它的位置,同时我将UIElement拖入Canvas里面呢?

2 个答案:

答案 0 :(得分:0)

我没有对此进行测试,但您可以尝试更换(或添加)您的调用,以禁用/重新启用滚动条可见性,并调用禁用/重新启用ScrollViewer控件本身:

private void MapItem_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
    Scroller.IsEnabled = false;
}

private void MapItem_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
    Scroller.IsEnabled = true;
}

如果它确实有效,它可能会在Style被禁用时影响Trigger,因此当IsEnabled属性等于False时,您可能需要使用{{1}}重新设置样式。 {1}}。

答案 1 :(得分:0)

我发现我需要在我的页面构造函数中设置ScrollViewer.ManipulationMode = ManipulationMode.Control,并且不要设置HorisontalScrollBarVisibility和VerticalScrollVarVisibility(它将偏移重置为0,0坐标)  现在它有效。

谢谢!