Похоже, что дети ScrollView не выходят за пределы представления?
Это происходит потому, что содержание Grid
имеет ограниченный размер, который точно размер сам по себе, но содержание ScrollViewer
не имеет ограниченный размер, так как это свитка возможность, а не как Grid
, дочерний элемент a ScrollViewer
всегда будет отображаться внутри него.
..., я хочу синие границы будут показаны на верхней части сетки
Чтобы быть честно, я думаю, что это не правильное направление, чтобы использовать Canvas.ZIndex
реализовать перетаскивание жест между разными родителями. Значение Canvas.ZIndex интерпретируется самым непосредственным родительским элементом Canvas, из которого установлено значение. Значение используется для явного определения порядка рисования в случаях, когда дочерние элементы перекрываются. В этом случае ваши Grid
и ScrollViewer
имеют один и тот же родительский элемент, но у Canvas
s есть разные родительские.
Здесь я могу дать вам метод для реализации этой функции: за
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="rootGrid"
PointerPressed="rootGrid_PointerPressed"
PointerReleased="rootGrid_PointerReleased">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Canvas x:Name="canvas" Grid.Column="1" Background="Wheat">
<Border BorderThickness="2" BorderBrush="Red" Width="50" Height="50" />
<Ellipse Width="50" Height="50" VerticalAlignment="Top" Fill="Red" />
</Canvas>
<ScrollViewer x:Name="scrollViewer" Grid.Column="0"
VerticalScrollMode="Enabled" VerticalScrollBarVisibility="Hidden"
Background="LightBlue">
<Canvas Width="100" x:Name="canvasInsideScrollViewer">
<Border BorderThickness="2" BorderBrush="Blue" Width="50" Height="50" VerticalAlignment="Bottom" />
</Canvas>
</ScrollViewer>
</Grid>
Код:
public Page20()
{
this.InitializeComponent();
this.Loaded += Page20_Loaded;
}
private void Page20_Loaded(object sender, RoutedEventArgs e)
{
gridRect = canvas.TransformToVisual(rootGrid).TransformBounds(new Rect(0.0, 0.0, canvas.ActualWidth, canvas.ActualHeight));
scrollViewerRect = scrollViewer.TransformToVisual(rootGrid).TransformBounds(new Rect(0.0, 0.0, scrollViewer.ActualWidth, scrollViewer.ActualHeight));
}
private Rect gridRect;
private Rect scrollViewerRect;
private FrameworkElement MoveElement;
private void rootGrid_PointerPressed(object sender, PointerRoutedEventArgs e)
{
var pointer = e.GetCurrentPoint(rootGrid);
if (gridRect.Left <= pointer.Position.X && pointer.Position.X <= gridRect.Right &&
gridRect.Top <= pointer.Position.Y && pointer.Position.Y <= gridRect.Bottom)
{
foreach (var childElement in canvas.Children)
{
var element = childElement as FrameworkElement;
Rect childBounds = element.TransformToVisual(rootGrid).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
if (childBounds.Left <= pointer.Position.X && pointer.Position.X <= childBounds.Right &&
childBounds.Top <= pointer.Position.Y && pointer.Position.Y <= childBounds.Bottom)
{
MoveElement = element;
canvas.Children.Remove(element);
}
}
}
else if (scrollViewerRect.Left <= pointer.Position.X && pointer.Position.X <= scrollViewerRect.Right &&
scrollViewerRect.Top <= pointer.Position.Y && pointer.Position.Y <= scrollViewerRect.Bottom)
{
foreach (var childElement in canvasInsideScrollViewer.Children)
{
var element = childElement as FrameworkElement;
Rect childBounds = element.TransformToVisual(rootGrid).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
if (childBounds.Left <= pointer.Position.X && pointer.Position.X <= childBounds.Right &&
childBounds.Top <= pointer.Position.Y && pointer.Position.Y <= childBounds.Bottom)
{
MoveElement = element;
canvasInsideScrollViewer.Children.Remove(element);
}
}
}
}
private void rootGrid_PointerReleased(object sender, PointerRoutedEventArgs e)
{
var pointer = e.GetCurrentPoint(rootGrid);
if (MoveElement != null)
{
if (gridRect.Left <= pointer.Position.X && pointer.Position.X <= gridRect.Right &&
gridRect.Top <= pointer.Position.Y && pointer.Position.Y <= gridRect.Bottom)
{
var canvasPointer = e.GetCurrentPoint(canvas);
canvas.Children.Add(MoveElement);
Canvas.SetLeft(MoveElement, canvasPointer.Position.X);
Canvas.SetTop(MoveElement, canvasPointer.Position.Y);
}
else if (scrollViewerRect.Left <= pointer.Position.X && pointer.Position.X <= scrollViewerRect.Right &&
scrollViewerRect.Top <= pointer.Position.Y && pointer.Position.Y <= scrollViewerRect.Bottom)
{
var scrollviewPointer = e.GetCurrentPoint(canvasInsideScrollViewer);
canvasInsideScrollViewer.Children.Add(MoveElement);
Canvas.SetLeft(MoveElement, scrollviewPointer.Position.X);
Canvas.SetTop(MoveElement, scrollviewPointer.Position.Y);
}
}
MoveElement = null;
}
Как вы можете видеть, я изменил Grid
во второй колонке Canvas
, так элемент может отображаться в абсолютном положении в качестве точки мыши.Вот рендеринг изображение моих демо: 
Здесь наиболее запутанная часть является то, что вы хотите перевести UIElement
между различным материнским управлением, но если вы кладете Border
с (который вы хотите перетащить и падение) также в rootGrid
, ваш Grid
, ScrollViewer
, Border
s будет иметь один и тот же родительский элемент, после чего вы сможете выполнить CustomBehaviorControl из XAMLBehaviorsSample, чтобы завершить работу по перетаскиванию.
Хорошо, спасибо за пояснение по z-index. Я понимаю, что это может быть не лучшее решение для реализации функции перетаскивания, которую я хочу. Что может быть непонятно из моего вопроса, так это то, что я хочу, чтобы элементы были видны при перетаскивании, вот в чем проблема. –
@JonatanBlom, но можно ли его опустить и сбросить в одном и том же родительском элементе управления? Это не будет иметь никакого значения только с предоставленного макета. –