1

我试图在 Surface 的 WPF 中消除 TouchDevices,这样我就可以忽略非手指触摸,因为 blob 似乎会触发我不想要的事件。
起初我有这样简单的事情

private void SurfaceWindow1_PreviewTouchDown(object sender, TouchEventArgs e)
    {
        if (!e.TouchDevice.GetIsFingerRecognized() && InteractiveSurface.PrimarySurfaceDevice.IsFingerRecognitionSupported == true)
        {
            e.Handled = true;
        }

    }

这可以很好地停止与 ScatterViewItems 内部和操作等事物的触摸交互。但是,在 PreviewTouchDown 之前肯定会发生其他事情,因为我可以使用 blob 激活 SVI 并将其置于顶部,尽管没有发生其他操作。我猜 SVI 上的 TouchEnter 仍然会显示并将其向前推进,但在所有元素上处理 TouchEnter 会给我同样的事情,所以还有其他事情发生。

我查看了 Touch.FrameReported,但在 SVI 听到它之前我无法释放正确的 TouchCaptures

    private void myTouchFrameHandler(object sender, TouchFrameEventArgs e)
    {
        foreach (TouchPoint _tp in e.GetTouchPoints(this)) {
            if (!_tp.TouchDevice.GetIsFingerRecognized())
            {
                this.ReleaseAllTouchCaptures();    
            }
        }
    }

有任何想法吗?
谢谢

4

3 回答 3

2

我偶然发现了同样的问题并为 ScatterViewItems 实现了附加行为。此行为禁用自动 IsTopmostOnActivation 行为并侦听 PreviewTouchDown 事件以根据测试条件决定是否将项目置于顶部。它具有易于使用的激活方法

CustomTopmostBehavior.Activate();

它添加了一个应用程序范围的样式,支持所有 ScatterViewItems 的行为。

可以通过设置默认情况下的 TestCondition 属性来自定义行为:

CustomTopmostBehavior.TestCondition = (t) =>
{
    return t.GetIsFingerRecognized();
};
于 2012-03-18T13:09:51.647 回答
1

好的,这是我的肮脏解决方法,以阻止触摸未被识别为手指时前进,并阻止 SVI 在悬停时上升到顶部。

    this.PreviewTouchDown += new EventHandler<System.Windows.Input.TouchEventArgs>(SurfaceWindow1_PreviewTouchDown);    
    SVI.TouchEnter += new EventHandler<TouchEventArgs>(SVI_TouchEnter);
    SVI.TouchLeave +=new EventHandler<TouchEventArgs>(SVI_TouchLeave);

    void SurfaceWindow1_PreviewTouchDown(object sender, System.Windows.Input.TouchEventArgs e)
    {

        if (!e.TouchDevice.GetIsFingerRecognized() && Microsoft.Surface.Presentation.Input.InteractiveSurface.PrimarySurfaceDevice.IsFingerRecognitionSupported) { e.Handled = true; }
        else
        {
           //normal stuff
        }



    }
    private void SVI_TouchEnter(object sender, TouchEventArgs e)
    {
        ScatterViewItem svi = sender as ScatterViewItem;

        if (!e.TouchDevice.GetIsFingerRecognized() && Microsoft.Surface.Presentation.Input.InteractiveSurface.PrimarySurfaceDevice.IsFingerRecognitionSupported == true)
        {
            svi.IsTopmostOnActivation = false;
            e.Handled = true;
        }
        else
        {
            foreach(ScatterViewItem svi in mainScatterView.Items.SourceCollection){
                svi.IsTopmostOnActivation = false;
            }

            SVI.IsTopmostOnActivation = true;
        }

    }
    private void SVI_TouchLeave(object sender, TouchEventArgs e)
    {
            ScatterViewItem svi = sender as ScatterViewItem;
            svi.IsTopmostOnActivation = true;
    }

想出这样一个不明智的方法,我感到很恶心。但由于没有隧道式 TouchEnter,您必须检查所有获得 TouchEnter 的可视化树对象,这会更糟。另外,我只是不知道如何使用受保护的方法 TouchDevice.Deactivate() 。但由于 SVI 无论如何都会捕获 touchDevice 并重新堆叠,因此我发现将它们保持在适当位置的唯一方法是使用 TopmostOnActivation 属性,然后在 Window 上捕获 PreviewTouchDown 并扔掉非手指。

必须有更好的方法来进入触摸层次,对吧?

于 2012-02-29T16:23:13.450 回答
0

好的,所以我已经深入挖掘了触摸层次结构。首先,TouchEnter 发生在所有 TouchDown 发生之前,但是没有隧道事件。TouchFrameHandler 在所有事件完成后发生,所以把它扔掉。

然后我意识到在 UIElements 上释放捕获对我的问题并没有真正的影响,因为 Touch 已经被捕获。所以我需要在每个元素上消除 TouchEnter 中的 TouchDevice。TouchDevice 中有一个 Deactivate 方法,但它受到保护。如果我能弄清楚如何停用 TouchDevice,我认为这应该可以解决问题。这听起来合理吗?如果是这样,我必须弄清楚如何覆盖受保护的方法。

于 2012-02-24T17:08:30.993 回答