2016-09-12 107 views
0

在Windows 10(UWP)中實現UI的元素可以使用從菜單區域拖放到滾動視圖區域來移動,也應該可以移動元素回到ScrollView的菜單區域。當元素從菜單移動到ScrollView時,該元素作爲菜單的子元素被刪除,並作爲子元素添加到ScrollView的子元素中。在滾動視圖區域之外渲染/繪製滾動視圖的子項

但是當我嘗試將元素移回時,它們在菜單後面呈現。我已經玩弄了z索引以及元素在XAML中的順序,並且測試了它們以在運行時刪除並重新添加ScrollView,以便將它放在頂部,但沒有運氣。

類似ScrollView子項的接縫不會在視圖之外繪製?有關如何解決這個問題的任何建議?

下面是說明問題的一些示例代碼:

<Page x:Class="ScrollViewTest.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:ScrollViewTest" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 
<Grid Background="Transparent" 
     Height="200" 
     Width="200"> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="100"></ColumnDefinition> 
     <ColumnDefinition Width="100"></ColumnDefinition> 
    </Grid.ColumnDefinitions> 
    <Grid Grid.Column="1" 
      Canvas.ZIndex="1" 
      Background="Transparent"> 
     <Canvas Background="Transparent" 
       Height="0" 
       Width="0" 
       VerticalAlignment="Top" 
       HorizontalAlignment="Left"> 
      <Border Canvas.Left="-25" 
        Canvas.Top="100" 
        BorderThickness="2" 
        BorderBrush="Red" 
        Width="50" 
        Height="50"></Border> 
     </Canvas> 
    </Grid> 
    <ScrollViewer Grid.Column="0" 
        VerticalScrollMode="Enabled" 
        Canvas.ZIndex="2" 
        Background="Transparent"> 
     <Canvas Background="Transparent" 
       Height="0" 
       Width="0" 
       VerticalAlignment="Top" 
       HorizontalAlignment="Left"> 
      <Border Canvas.Left="75" 
        BorderThickness="2" 
        BorderBrush="Blue" 
        Width="50" 
        Height="50"></Border> 
     </Canvas> 
    </ScrollViewer> 
</Grid> 

而結果,我想對電網

回答

0
的頂部顯示藍色邊框

似乎像ScrollView的孩子不吸引視野外?

這是因爲Grid內容的大小有限這也正是本身的大小,而是ScrollViewer的內容沒有限制大小,因爲它是滾動能,不喜歡Grid,的子元素一個ScrollViewer將始終在其內部呈現。

...,我想對電網的頂部顯示藍色邊框

要坦率地說,我認爲這是不使用Canvas.ZIndex實現拖放正確的方向不同父母之間的姿態。 Canvas.ZIndex值由設置值的最直接的父Canvas元素解釋。該值用於在子元素重疊的情況下顯式定義繪製順序。在這種情況下,您的GridScrollViewer具有相同的父代,但Canvas有不同的父代。

在這裏我可以給你一個方法來實現這個功能:

<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; 
} 

正如你所看到的,我在第二列改GridCanvas,使該元素可以作爲鼠標點呈現在絕對位置。這裏是我的演示的渲染圖像: enter image description here

這裏最令人困惑的是,你要翻譯不同的父控件之間UIElement,但如果你把你的Border S(要拖放)也rootGrid,你的Grid,,Borders會有相同的父母,那麼你可以按照CustomBehaviorControlXAMLBehaviorsSample來完成拖放工作。

+0

好的,謝謝澄清z-index。我意識到這可能不是實現我想要的拖放功能的最佳解決方案。從我的問題中可能不清楚的是,我希望元素在拖動時可見,這是問題出現的地方。 –

+0

@JonatanBlom,但它可以被拖放到相同的父控件中嗎?它僅僅從渲染的佈局上不會有什麼不同。 –

相關問題