WPF AutomationPeer Crash on TouchScreen Devices

2019-06-16 11:13发布

I created a WPF application. It works completely fine on desktops but the moment the application is ran on a touchscreen it crashes. I've turned off touchscreen processes and the application worked completely fine. I'm wondering has anyone found a "better" fix than to disable touchscreen processes, as this would not work on the microsoft surface or and windows tablet.

I'm currently using .Net 4.5

1条回答
Deceive 欺骗
2楼-- · 2019-06-16 11:25

I have had many problems with WPF AutomationPeer too.

You might be able to solve your problem by forcing your WPF UI elements to use a custom AutomationPeer that behaves differently to the default one by not returning AutomationPeers of child controls. This might stop any UI automation stuff working, but hopefully in your case, as in mine, you are not using UI automation..

Create a custom automation peer class that inherits from FrameworkElementAutomationPeer and overrides the GetChildrenCore method, to return an empty list instead of the child control automation peers. This should stop problems occuring when something attempts to iterate through the tree of AutomationPeers.

Also override the GetAutomationControlTypeCore to specify the control type that you will use the automation peer on. In this example I am passing the AutomationControlType as a constructor parameter. If you apply your custom automation peer to your Windows it should solve your problems as I think the root element is used to return all children.

public class MockAutomationPeer : FrameworkElementAutomationPeer
{
    AutomationControlType _controlType;

    public MockAutomationPeer(FrameworkElement owner, AutomationControlType controlType)
        : base(owner)
    {
        _controlType = controlType;
    }

    protected override string GetNameCore()
    {
        return "MockAutomationPeer";
    }

    protected override AutomationControlType GetAutomationControlTypeCore()
    {
        return _controlType;
    }

    protected override List<AutomationPeer> GetChildrenCore()
    {
        return new List<AutomationPeer>();
    }
}

To use the custom automation peer override the OnCreateAutomationPeer method in your UI element e.g. Window:

protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
    return new MockAutomationPeer(this, AutomationControlType.Window);
}
查看更多
登录 后发表回答