簡體   English   中英

如何使我的Rectangle對觸摸事件做出反應,就像對鼠標/指針事件一樣?

[英]How can I make my Rectangle react to touch events like it does for mouse/pointer events?

在我的MainPage上,我有一個充滿彩色矩形的Stackpanel,它們都以Margin設置為(0,5,0,5)開頭。 我想允許用戶僅水平移動這些矩形。 由於矩形沒有鼠標事件,因此我使用了指針來實現這一點。 流程是:用戶點擊一個Rectangle來選擇它,更改光標以提供視覺提示,用戶向左或向右拖動Rectangle。 (請注意,Stackpanel確實有一個垂直滾動查看器)。 這是我的C#代碼:

private void Rectangle_FirstClick(object sender, EventArgs e)
{
    // Give rectangle a white border to imply selection
    Rectangle myControl = sender as Rectangle;
    myControl.StrokeThickness = 1;
    myControl.Stroke = new SolidColorBrush(Color.FromArgb(255, 240, 240, 240));

    // Provide visual cue to mouse users by changing the pointer immediately
    Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeWestEast, 0);

    // Handle mouse leaving/re-entering the track piece
    myControl.PointerEntered += MyControl_PointerEntered;
    myControl.PointerExited += MyControl_PointerExited;

    // Handle the drag event
    myControl.PointerPressed += MyControl_PointerPressed;
    myControl.PointerReleased += MyControl_PointerReleased;
    myControl.PointerMoved += MyControl_PointerMoved;
}

以下是各個事件處理程序

bool PossibleDragStart = false;
Point InitialDragPoint = new Point(0, 0);

private void MyControl_PointerExited(object sender, PointerRoutedEventArgs e)
{
    Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Arrow, 0);
}

private void MyControl_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeWestEast, 0);
}

private void MyControl_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    PossibleDragStart = true;
    InitialDragPoint = e.GetCurrentPoint(sender as Rectangle).Position;
}

private void MyControl_PointerReleased(object sender, PointerRoutedEventArgs e)
{
    PossibleDragStart = false;
}

private void MyControl_PointerMoved(object sender, PointerRoutedEventArgs e)
{
    // If pointer pressed without release, and then moved, we are dragging
    if (PossibleDragStart)
    {
        Point CurrentDragPoint = e.GetCurrentPoint(AudioTracksRightContainer).Position;
        StatusBar.Text = CurrentDragPoint.X.ToString();

        // Calculate drag offset by subtracting Current Position from Initial Position
        double SegmentMargin = CurrentDragPoint.X - InitialDragPoint.X;

        // Move the Rectangle with the pointer drag
        Rectangle trackSegment = sender as Rectangle;
        trackSegment.Margin = new Thickness(SegmentMargin, 5, 0, 5);
    }
}

該代碼非常適合鼠標使用,但是當我嘗試使用它進行觸摸時,我必須按住以啟動拖動,即使那樣,矩形在放置前也只移動了幾個單位。 我不確定為什么行為會有所不同。

此代碼的另一個問題是,如果矩形足夠窄,以至於當我快速拖動並且矩形無法跟上光標時,當光標離開矩形邊界時,它將停止拖動。 比觸摸無法解決的問題小得多,但仍然有點煩人。

聽起來好像ScrollViewer正在捕獲觸摸事件以進行自己的滾動。 您可以使用Xaml的操縱引擎來注冊操縱事件,以手動操縱操縱。 這不僅更容易編碼,而且效率更高。 默認情況下,它將適用於觸摸和鼠標。

<Rectangle Margin="5" Fill="Orange" Height="100" Width="200"
           ManipulationMode="TranslateX"
           ManipulationDelta="Rectangle_ManipulationDelta"
           >
    <Rectangle.RenderTransform>
        <CompositeTransform />
    </Rectangle.RenderTransform>
</Rectangle>

在Rectangle_ManipulationDelta方法中,轉換矩形:

private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    UIElement elem = sender as UIElement;
    CompositeTransform ct = elem.RenderTransform as CompositeTransform;

    ct.TranslateX += e.Delta.Translation.X;
}

如果只需要平移,則可以使用TranslateTransform而不是CompositeTransform,或者可以添加旋轉和縮放。

有關使用手勢和操縱事件的更多信息,請參見快速入門:觸摸輸入(XAML)

我在博客條目中討論了ScrollViewer接管指針處理的問題我所有的手勢都去了哪里? 如果您真的想自己處理指針事件,我將討論如何在拖動過程中禁用ScrollViewer。 您可以通過捕獲指針來處理手指移動快於目標的情況。 如果您處理操作事件,則不需要此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM