拖放在ScrollViewer中不起作用

时间:2017-01-13 01:52:23

标签: c# wpf

我的问题是当我将画布包裹在scrollviewer中时,边框的拖放变得不起作用。

1200x1200画布放入500x500滚动查看器。我希望画布在scrollviewer中可滚动(触摸幻灯片)。在我插入scrollviewer之前,画布中的拖放效果非常好。

MainWindow.xaml

<Grid ClipToBounds="True">
        <ScrollViewer Name="scbb" Width="500" Height="500" HorizontalScrollBarVisibility="Hidden" 
            VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Left"  
            VerticalAlignment="Top" Background="LightBlue" ScrollViewer.CanContentScroll="True">
        <Canvas x:Name="canvas" Width="1200" Height="1200"
            MouseLeftButtonDown="CanvasMouseLeftButtonDown"
            MouseLeftButtonUp="CanvasMouseLeftButtonUp"
            MouseMove="CanvasMouseMove">
        </Canvas>
        </ScrollViewer>
        <Button x:Name="btnEnable" Content="Enable" Height="50" Width="50" Margin="0,0,115,10" VerticalAlignment="Bottom" 
            HorizontalAlignment="Right" Click="btnEnable_Click"/>
        <Button Content="Add Image" Width="100" Height="100" VerticalAlignment="Bottom" 
            HorizontalAlignment="Right" Click="AddButtonClick" Margin="0,0,10,10"/>
    </Grid>

MainWindow.xaml.cs

private void AddButtonClick(object sender, RoutedEventArgs e)
        {
            int iNum = SETTING.GetTableRunningNumber();

            var borderWrap = new Border();
            borderWrap.Width = 100;
            borderWrap.Height = 100;
            borderWrap.Background = Brushes.Green;

            var label1 = new Label();
            label1.VerticalAlignment = VerticalAlignment.Center;
            label1.HorizontalAlignment = HorizontalAlignment.Center;
            label1.Content = "Table " + iNum.ToString();
            label1.Name = "Table" + iNum.ToString();
            label1.Foreground = Brushes.White;
            label1.FontWeight = FontWeights.Bold;

            borderWrap.Child = label1;
            borderWrap.MouseDown += TableMouseDown;

            Canvas.SetLeft(borderWrap, 10);
            Canvas.SetTop(borderWrap, 10);
            canvas.Children.Add(borderWrap);

            iNum += 1;
            SETTING.SetTableRunningNumber(iNum);
        }

        private Point mousePosition;
        private Border draggedBorder;

        private void TableMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!SETTING.GetEnableDrag())
            {
                var cLabel = e.Source as Label;
                var bBorder = e.Source as Border;

                if (cLabel != null)
                {
                    MessageBox.Show(cLabel.Name.ToString());
                }
            }
        }

        private void CanvasMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (SETTING.GetEnableDrag())
            {
                var dBorder = e.Source as Border;
                var cLabel = e.Source as Label;

                if (dBorder == null)
                {
                    dBorder = (Border)cLabel.Parent;
                }

                if (dBorder != null && canvas.CaptureMouse())
                {
                    mousePosition = e.GetPosition(canvas);
                    draggedBorder = dBorder;
                    Panel.SetZIndex(draggedBorder, 1);
                }
            }           
        }

        async Task PutTaskDelay100()
        {
            await Task.Delay(100);
        }

        private async void CanvasMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (SETTING.GetEnableDrag())
            {
                await PutTaskDelay100();
                if (draggedBorder != null)
                {
                    canvas.ReleaseMouseCapture();
                    Panel.SetZIndex(draggedBorder, 0);
                    draggedBorder = null;
                }

            }
        }

        private void CanvasMouseMove(object sender, MouseEventArgs e)
        {
            if (SETTING.GetEnableDrag())
            {
                double canvasSize = 1200;
                if (draggedBorder != null)
                {
                    var position = e.GetPosition(canvas);
                    var offset = position - mousePosition;
                    mousePosition = position;

                    double newTop = Canvas.GetTop(draggedBorder) + offset.Y;
                    double newLeft = Canvas.GetLeft(draggedBorder) + offset.X;

                    if (newTop < 0)
                    {
                        newTop = 0;
                    }
                    else if (newTop + draggedBorder.ActualWidth > canvasSize)
                        newTop = canvasSize - draggedBorder.ActualWidth;

                    if (newLeft < 0)
                    {
                        newLeft = 0;
                    }
                    else if (newLeft + draggedBorder.ActualWidth > canvasSize)
                        newLeft = canvasSize - draggedBorder.ActualWidth;

                    Canvas.SetLeft(draggedBorder, newLeft);
                    Canvas.SetTop(draggedBorder, newTop);
                }
            }       
        }

1 个答案:

答案 0 :(得分:1)

几个月前我遇到了这个问题,并在后面的代码中解决了这些问题。

在WindowMain.xaml.cs中的InitializeComponent之后添加:

Object.freeze

我的程序只是从我在ScrollViewer上放置的资源管理器文件列表中加载一个删除的文件。必须设置ScrollViewer中的 public WindowMain() { InitializeComponent(); // your code, etc. scrollViewer.AllowDrop = true; scrollViewer.PreviewDragEnter += scrollViewer_PreviewDragEnter; scrollViewer.PreviewDragOver += scrollViewer_PreviewDragOver; scrollViewer.Drop += scrollViewer_Drop; } void scrollViewer_PreviewDragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.None; } } void scrollViewer_PreviewDragOver(object sender, DragEventArgs e) { e.Handled = true; } bool IsDataAvailable = false; void scrollViewer_Drop(object sender, DragEventArgs e) { // Get data object var dataObject = e.Data as DataObject; // Check for file list if (dataObject.ContainsFileDropList()) { // Process file names StringCollection fileNames = dataObject.GetFileDropList(); bool isIsDataAvailable = false; try { var uri = new Uri(fileNames[0]); BitmapSource imageSource = new BitmapImage(uri); isIsDataAvailable = true; } catch (Exception error) { string errorMessage = error.ToString(); } finally { IsDataAvailable = isIsDataAvailable; } } } 。以及处理基本拖放的例程。 ScrollViewer允许删除后,您的代码应该可以正常工作。