4

我有一个项目需要能够在屏幕上拖动用户控件(托管在网格内)。这适用于以下代码:

void MyUserControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var ct = (CompositeTransform) RenderTransform ?? new CompositeTransform {CenterX = 0.5, CenterY = 0.5};
        ct.TranslateX += e.Delta.Translation.X;
        ct.TranslateY += e.Delta.Translation.Y;
}

问题是用户控件可以一直拖出屏幕区域。为了防止这种情况,我尝试了此处显示的示例:http: //msdn.microsoft.com/en-us/library/system.windows.uielement.manipulationdelta.aspx

不幸的是,它使用了containsRect.Contains(shapeBounds),而在 Windows 8 中,我们希望将 shapeBounds(this is a rect) 替换为 Point。我不确定如何使用它。

那么问题来了,我们如何确保用户控件或任何 UIElement 不能被拖出 windows 8 商店应用程序中的 Window.Current.Bounds 区域?

谢谢。

编辑:有关 xaml 结构的更多详细信息:

主页包含一个水平和垂直对齐设置为拉伸的网格。根据需要将用户控件添加到此网格中。每个用户控件都有一个包含 3 个不同视图(全屏、窗口和小)的父网格。根据用户的选择显示视图。只有在显示窗口网格时才必须应用拖动行为。所以我们有这个

<Grid> <!-- this is the parent grid on mainpage with horizontal and vertical alignment to stretch-->
   <Grid> <!-- this is the usercontrol's main grid (added to above grid via code). This grid must be draggable if the below grid is window -->
         <Grid /> <!-- this is one of the child grids that is shown based on user's choice (fullscreen, window or small view).-->
   </Grid>
</Grid>

在更改布局方面我没有太多选择。在用户控件中使用上述 ManipulationDelta 事件(根据显示的子网格启用/禁用),我能够获得拖动行为,但控件可能会超出窗口范围。那么有什么方法可以通过代码而不是 xaml 在 WinRTXamlToolkit 中添加以下 FlickBehavior 或根据某些条件启用/禁用行为?

<i:Interaction.Behaviors>
   <views:HeavyFlickBehavior />
</i:Interaction.Behaviors>
4

1 回答 1

4

您可以查看FlickBehaviorWinRT XAML 工具包中的示例,了解如何使用 parentCanvasCanvas.Top/Leftproperties 而不是来实现这一点RenderTransform,假设Canvas定义了您的界限。

这是一个摘要:

private void OnAssociatedObjectManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)
{
    _startPosition = new Point(
        Canvas.GetLeft(this.AssociatedObject),
        Canvas.GetTop(this.AssociatedObject));
}

private void OnAssociatedObjectManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs manipulationDeltaRoutedEventArgs)
{
    var dx = manipulationDeltaRoutedEventArgs.Cumulative.Translation.X;
    var dy = manipulationDeltaRoutedEventArgs.Cumulative.Translation.Y;

    var x = _startPosition.X + dx;
    var y = _startPosition.Y + dy;

    if (manipulationDeltaRoutedEventArgs.IsInertial)
    {
        while (x < 0 ||
               x > _canvas.ActualWidth - this.AssociatedObject.ActualWidth)
        {
            if (x < 0)
                x = -x;
            if (x > _canvas.ActualWidth - this.AssociatedObject.ActualWidth)
                x = 2 *
                    (_canvas.ActualWidth - this.AssociatedObject.ActualWidth) -
                    x;
        }

        while (y < 0 ||
               y > _canvas.ActualHeight - this.AssociatedObject.ActualHeight)
        {
            if (y < 0)
                y = -y;
            if (y > _canvas.ActualHeight - this.AssociatedObject.ActualHeight)
                y = 2 * (_canvas.ActualHeight - this.AssociatedObject.ActualHeight) -
                    y;
        }
    }
    else
    {
        if (x < 0)
            x = 0;
        if (x > _canvas.ActualWidth - this.AssociatedObject.ActualWidth)
            x = _canvas.ActualWidth - this.AssociatedObject.ActualWidth;
        if (y < 0)
            y = 0;
        if (y > _canvas.ActualHeight - this.AssociatedObject.ActualHeight)
            y = _canvas.ActualHeight - this.AssociatedObject.ActualHeight;
    }

    Canvas.SetLeft(this.AssociatedObject, x);
    Canvas.SetTop(this.AssociatedObject, y);
}
于 2013-04-04T14:34:37.270 回答