0

我有一个 ScrollViewer,里面有一些扩展器,扩展器的内容有一个画布。我在 Canvas 上绘制了两个矩形,它们是可以拖动的 Thumb 控件。问题是,每当我按下矩形并尝试拖动时,它都会以某种方式假定我想滚动整个页面并且拖动永远不会发生。如何在 ScrollViewer 中解决此问题。

我在 MSDN for UWP 上看到了一个名为的属性CanBeScrollAnchor,它说该属性用于(获取或设置一个值,该值指示 UIElement 是否可以成为滚动锚定的候选对象。)。但是将其设置为 false 并没有帮助。(我添加 WPF 标记是因为概念相同)。请帮忙

编辑:此问题仅发生在触摸屏上。

<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Hidden">
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">
<uwpControls:Expander>
<!--Some Content-->
</uwpControls:Expander>

<uwpControls:Expander HeaderStyle="{StaticResource ToggleButtonFullWidthHeader}"
                              Background="{StaticResource ListViewItemBackgroundBrush}" Margin="0,20,0,0" HorizontalAlignment="Stretch" Header="DragDrop">

                    <Grid x:Name="gridBarImagePanel" Grid.Row="4" BorderBrush="Black" BorderThickness="2">

                        <uwpControls:ImageEx x:Name="BarCodeImage" IsCacheEnabled="True" Source="..\SampleImage\demo.png" 
                                 Stretch="UniformToFill" />

                        <Canvas x:Name="cnvBarCodeImage" Canvas.ZIndex="100" VerticalAlignment="Stretch">

                        </Canvas>
                    </Grid>
                </uwpControls:Expander>

</StackPanel> 
</ScrollViewer>

在后面的代码中,我调用此方法在 Canvas 上动态绘制两个 Thumb 控件。

public sealed partial class SomeControl:Page
{
event Action<Thumb, double, double> ChangeDimensions;

public void OnSomeButtonClick(object sender,EventArgs e)
{
 //TEST(Remove this)
                dimensions.Add(new Dimensions()
                {
                    Height = 80,
                    Width = 150,
                    left = 250,
                    Top = 40,
                    BorderColor = BrushCollection[0],
                    MaxLeftPossible = null,
                    MaxTopPossible = null,//280
                    MaxRightPossible = null,
                    MaxBottomPossible = null,
                });
                dimensions.Add(new Dimensions()
                {
                    Height = 80,
                    Width = 150,
                    left = 250,
                    Top = 150,
                    BorderColor = BrushCollection[1],
                    MaxLeftPossible = null,
                    MaxTopPossible = null,//280
                    MaxRightPossible = null,
                    MaxBottomPossible = null,
                });
                //CreateUIShapes(SelectedRowItem.WindowLocations.Count, dimensions);
                CreateUIShapes(2, dimensions);

}
       private void CreateUIShapes(int numberOfWindows, List<Dimensions> dimensions)
            {
                Thumb th = null;
                for (int i = 0; i < numberOfWindows; i++)
                {
                    th = new Thumb();
                    th.Name = string.Format("{0}{1}", "Thumb", i + 1);
                    var item = dimensions[i];
                    th.Width = item.Width;
                    th.Height = item.Height;
                    th.Foreground = new SolidColorBrush(Windows.UI.Colors.Transparent);
                    th.BorderBrush = item.BorderColor;
                    th.BorderThickness = new Thickness(3);
                    th.DragDelta += (sender, e) => Th_DragDelta(sender, e, dimensions);
                    th.DragCompleted += (sender, e) => Th_DragCompleted(sender, e);
                    Canvas.SetLeft(th, CheckAndGetItemToLeft(item.left, i));
                    Canvas.SetTop(th, CheckAndGetItemTotop(item.Top, i));
                    cnvBarCodeImage.Children.Add(th);
                }
            }

//This is the code to drag and drop.    
     private void Th_DragDelta(object sender, DragDeltaEventArgs e, List<Dimensions> LimitedWindowMovements)
        {
            var SelectedDraggableThumb = sender as Thumb;
            double left = (Canvas.GetLeft(SelectedDraggableThumb) >= 0) ? Canvas.GetLeft(SelectedDraggableThumb) : 0;
            double top = (Canvas.GetTop(SelectedDraggableThumb) >= 0) ? Canvas.GetTop(SelectedDraggableThumb) : 0;

            if (ChkDualMode.IsChecked == true)
            {
                var OtherDraggableThumbs = cnvBarCodeImage.Children.OfType<Thumb>().Where(x => x != SelectedDraggableThumb);

                var maxTopSelected = LimitedWindowMovements[0].MaxTopPossible == null ? 1 : LimitedWindowMovements[0].MaxTopPossible;
                var maxBottomSelected = LimitedWindowMovements[0].MaxBottomPossible == null ? BarCodeImage.ActualHeight - SelectedDraggableThumb.ActualHeight : LimitedWindowMovements[0].MaxBottomPossible;
                var maxLeftSelected = LimitedWindowMovements[0].MaxLeftPossible == null ? 0 : LimitedWindowMovements[0].MaxLeftPossible;
                var maxRightSelected = LimitedWindowMovements[0].MaxRightPossible == null ? BarCodeImage.ActualWidth - SelectedDraggableThumb.Width : LimitedWindowMovements[0].MaxRightPossible;
                //Boundry case for top->Current element.
                //Don't allow further up.

                if (top < maxTopSelected) //Hardcoding for now. top < 1 original.
                {
                    if (e.VerticalChange <= 1)
                    {
                        ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                        return;
                    }
                }
                //Boundry case for bottom->Current element.
                //Don't allow further down.
                //Canvas.GetTop(SelectedDraggableThumb) >= BarCodeImage.ActualHeight - SelectedDraggableThumb.ActualHeight original.
                else if (Canvas.GetTop(SelectedDraggableThumb) >= maxBottomSelected)
                {
                    if (e.VerticalChange > 0)
                    {
                        ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                        return;
                    }
                }
                //Boundry case for left->Current element.
                //Don't allow further left.
                //Canvas.GetLeft(SelectedDraggableThumb) <= 0 original.
                else if (Canvas.GetLeft(SelectedDraggableThumb) <= maxLeftSelected)
                {
                    if (e.HorizontalChange <= 1)
                    {
                        ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                        return;
                    }
                }
                //Boundry case for left->Current element.
                //Don't allow further right.
                //Math.Round(Canvas.GetLeft(SelectedDraggableThumb), 1) >= BarCodeImage.ActualWidth - SelectedDraggableThumb.Width original.
                else if (Math.Round(Canvas.GetLeft(SelectedDraggableThumb), 1) >= maxRightSelected)
                {
                    if (e.HorizontalChange >= 0)
                    {
                        ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                        return;
                    }
                }
                //There may be n number of windows.
                foreach (var item in OtherDraggableThumbs)
                {
                    //Boundry case for the other thumb moving up.
                    //Don't allow further up.
                    //var OtherTop = Canvas.GetTop(item); original
                    var OtherTop = Canvas.GetTop(item);
                    if (OtherTop < maxTopSelected)
                    {
                        if (e.VerticalChange <= 1)
                        {
                            ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                            return;
                        }
                    }

                    //Boundry case for the other thumb moving bottom
                    //Don't allow further bottom.
                    //BarCodeImage.ActualHeight - SelectedDraggableThumb.ActualHeight original
                    if (Canvas.GetTop(item) >= maxBottomSelected)
                    {

                        if (e.VerticalChange > 0)
                        {
                            ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                            return;
                        }

                    }

                    //Boundry case for the other thumb moving left.
                    //Don't allow further left
                    //Canvas.GetLeft(item) <= 0 original
                    if (Canvas.GetLeft(item) <= maxLeftSelected)
                    {
                        if (e.HorizontalChange <= 1)
                        {
                            ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                            return;
                        }

                    }

                    //Boundry case for the other thumb moving right.
                    //Don't allow further right
                    //Math.Round(Canvas.GetLeft(item), 1) >= BarCodeImage.ActualWidth - item.Width original
                    if (Math.Round(Canvas.GetLeft(item), 1) >= maxRightSelected)
                    {
                        if (e.HorizontalChange >= 0)
                        {
                            ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
                            return;
                        }
                    }


                    if (ChangeDimensions == null)
                    {
                        ChangeDimensions += BarCodeServiceView_ChangeDimensions;
                    }

                }

                foreach (var item in OtherDraggableThumbs)
                {
                    ChangeDimensions?.Invoke(item, e.HorizontalChange, e.VerticalChange);
                }

            }

            left = (Canvas.GetLeft(SelectedDraggableThumb) > BarCodeImage.ActualWidth - SelectedDraggableThumb.ActualWidth) ? BarCodeImage.ActualWidth - SelectedDraggableThumb.ActualWidth : left;
            top = (Canvas.GetTop(SelectedDraggableThumb) > BarCodeImage.ActualHeight - SelectedDraggableThumb.ActualHeight) ? BarCodeImage.ActualHeight - SelectedDraggableThumb.ActualHeight : top;
            Canvas.SetLeft(SelectedDraggableThumb, left + e.HorizontalChange);
            Canvas.SetTop(SelectedDraggableThumb, top + e.VerticalChange);
        }

//When one thumb moves, I want to move the other in the same direction.
  private void BarCodeServiceView_ChangeDimensions(Thumb sender, double arg1, double arg2)
        {
            if (sender != null)
            {
                //4025e8df
                double left = (Canvas.GetLeft(sender) > 0) ? Canvas.GetLeft(sender) : 0;
                double top = (Canvas.GetTop(sender) > 0) ? Canvas.GetTop(sender) : 0;
                left = (Canvas.GetLeft(sender) > BarCodeImage.ActualWidth - sender.ActualWidth) ? BarCodeImage.ActualWidth - sender.ActualWidth : left;
                top = (Canvas.GetTop(sender) > BarCodeImage.ActualHeight - sender.ActualHeight) ? BarCodeImage.ActualHeight - sender.ActualHeight : top;
                Canvas.SetLeft(sender, left + arg1);
                Canvas.SetTop(sender, top + arg2);
            }
        }

    private void Th_DragCompleted(object sender, DragCompletedEventArgs e)
    {
    //Do something.
       foreach (var item in cnvBarCodeImage.Children.OfType<Thumb>())
        {
            ChangeDimensions -= BarCodeServiceView_ChangeDimensions;
        }
    }
}

 public class Dimensions
    {
        public double Height { get; set; }
        public double Width { get; set; }
        public double left { get; set; }
        public double Top { get; set; }
        public Windows.UI.Xaml.Media.Brush BorderColor { get; set; }
        /// <summary>
        /// If no restriction needed specify null
        /// </summary>
        public double? MaxTopPossible { get; set; }
        /// <summary>
        /// If no restriction needed specify null
        /// </summary>
        public double? MaxLeftPossible { get; set; }
        /// <summary>
        /// If no restriction needed specify null
        /// </summary>
        public double? MaxRightPossible { get; set; }
        /// <summary>
        /// If no restriction needed specify null
        /// </summary>
        public double? MaxBottomPossible { get; set; }
    }
4

0 回答 0