WPF и проблема с сенсорным экраном

У меня есть приложение WPF .NET 4.6, работающее на планшете Windows 8.1, и за последние несколько дней я изо всех сил старался сделать свое приложение touch дружественным, чтобы оно работало должным образом. Мои основные проблемы связаны с фокусом, они влияют на несколько элементов управления в моем приложении. например:

  • Текстовые файлы: иногда требуется двойное или тройное касание, чтобы получить фокус ввода, они вводят мышью по состоянию, но карет не существует;
  • ComboBoxes: требуется несколько касаний, чтобы открыть его, и после касания элемента, чтобы выбрать его, комбо остается открытым с выделенным выделенным элементом.
    проблема со списком задач
  • Кнопки: выполняет пару кликов для запуска подключенной команды и остается в состоянии мыши над состоянием;
  • Поддержка клавиатуры

Есть несколько подходов, которые я пробовал при поиске решения, у каждого из которых есть свои недостатки:

  • Удаление поддержки планшета для всего приложения (взято здесь). это решает большинство упомянутых выше проблем фокуса, но делает прокрутку (и я предполагаю, что некоторые другие функции, связанные с Tablet, которые я еще не нашел) непригодны.
  • Явная активация клавиатуры при необходимости (Пример здесь). Проблема с фокусом остается, прокрутка работает как ожидалось
  • Я также попытался удалить все стили и протестировать все на двух разных планшетах от разных производителей, но без успеха

Недавно Microsoft анонсировала, что "Touch лучше". Но я не мог найти официальную документацию о наилучшем способе подхода к этой теме.

Любое предложение о том, как заставить мое приложение работать лучше с прикосновением, будет большой помощью.

Ответ 1

Мне удалось удалить состояние над мышью, используя следующее поведение:

public class TouchDeviceMouseOverUIElementFixBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        AssociatedObject.StylusUp += AssociatedObject_StylusUp;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.StylusUp -= AssociatedObject_StylusUp;
    }

    private void AssociatedObject_StylusUp(object sender, StylusEventArgs e)
    {
        var control = sender as FrameworkElement;
        if (control != null)
        {
            if (!VisualStateManager.GoToElementState(control, "Normal", true))
            {
                VisualStateManager.GoToState(control, "Normal", true);
            }
        }
    }
}