Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ScrollViewer中带有可移动项目的可滚动画布_C#_.net_Wpf_Canvas_Windows Phone 8 - Fatal编程技术网

C# ScrollViewer中带有可移动项目的可滚动画布

C# ScrollViewer中带有可移动项目的可滚动画布,c#,.net,wpf,canvas,windows-phone-8,C#,.net,Wpf,Canvas,Windows Phone 8,我有一个包含画布的ScrollViewer。这个画布上有一些可移动的元素。以下是我的XAML代码: <ScrollViewer x:Name="Scroller" HorizontalScrollBarVisibility="Auto" Background="White"> <Canvas x:Name="MapCanvas" Width="4000" Height="4000"> <Button x:

我有一个包含画布的ScrollViewer。这个画布上有一些可移动的元素。以下是我的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;
        }
private void-MapItem\u-operationdelta(对象发送方,System.Windows.Input.operationDeltaEventargs e)
{
FrameworkElement btn=发送方作为FrameworkElement;
如果(null==btn)返回;
左双=Canvas.GetLeft(btn)+e.DeltaManipulation.Translation.X;
double-top=Canvas.GetTop(btn)+e.DeltaManipulation.Translation.Y;
if(左<0)
左=0;
else if(左>MapCanvas.ActualWidth-btn.ActualWidth)
左=MapCanvas.ActualWidth-btn.ActualWidth;
如果(顶部<0)
top=0;
else if(顶部>MapCanvas.ActualHeight-btn.ActualHeight)
top=MapCanvas.ActualHeight-btn.ActualHeight;
Canvas.SetLeft(btn,左);
Canvas.SetTop(btn,top);
e、 已处理=正确;
}
私有void MapItem_操作已完成(对象发送方,System.Windows.Input.OperationCompletedEventArgs e)
{
Scroller.HorizontalScrollBarVisibility=ScrollBarVisibility.Auto;
Scroller.VerticalScrollBarVisibility=ScrollBarVisibility.Auto;
e、 已处理=正确;
}
private void MapItem_操作已启动(对象发送方,System.Windows.Input.ManipulationStartedEventArgs e)
{
Scroller.HorizontalScrollBarVisibility=ScrollBarVisibility.Disabled;
Scroller.VerticalScrollBarVisibility=ScrollBarVisibility.Disabled;
e、 已处理=正确;
}
一切都很完美。但当ScrollViewer滚动到某个水平偏移量或垂直偏移量,并且我在可见区域中单击或点击任何UIElement时,ScrollViewer似乎会自动滚动到HorisontalOffset==0和VerticalOffset==0。然后,在释放UIElement之后,它会跳回。
如何避免这种行为并使ScrollViewer保持在原来的位置,同时将放置在其中的UIElement拖动到画布中?

我还没有测试过这一点,但您可以尝试用禁用/重新启用控件本身的调用替换(或添加)禁用/重新启用滚动条可见性的调用:

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

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

如果它确实起作用,则在禁用时可能会影响
样式
,因此,当它等于
False
时,您可能必须使用
IsEnabled
属性上的
触发器重新设置它的样式。我发现我需要在我的页面构造函数中设置ScrollViewer.ManipulationMode=ManipulationMode.Control,而不设置HorisontalScrollBarVisibility和VerticalScrollVarVisibility(它将偏移重置为0,0坐标)
现在它起作用了


谢谢!

问题是当ScrollViewer被禁用时,其中的所有元素也将被禁用。因此我无法移动它们:(我意识到这可能不是正确的路径,但是如果扩展
Canvas
控件,可以添加一个回调处理程序,在
IsEnabledProperty
更改时调用。然后在该处理程序中,当
Canvas更改时,可以将所有子项的
IsEnabled
属性设置为
true
已禁用。请看一个类似的示例,但它是针对
TabItem
控件的。