Используя WPF / MVVM, как я могу сразу же восстановить фокус моего приложения после закрытия внешнего процесса? - PullRequest
0 голосов
/ 18 января 2019

У меня полноэкранное приложение WPF, которое запускает внешние процессы, когда пользователь выбирает элемент из списка. Навигация по списку осуществляется в основном с помощью клавиатуры, а не мыши. Какой самый чистый способ немедленно вернуть фокус на список после того, как пользователь закрывает внешнее приложение? У меня это работает, но решение, на мой взгляд, не идеальное и немного "хакерское".

Вот XAML:

<ListBox SelectedIndex="{Binding ActiveSelection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                 IsSynchronizedWithCurrentItem="True" x:Name="ListBoxSelector">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

И код:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var process = Process.Start(@"C:\Windows\system32\mspaint.exe");
    process.WaitOnExit()
    ActiveSelection += 1;
    ActiveSelection -= 1;
}

Таким образом, в основном изменение ActiveSelection (и затем снова, чтобы та же самая вещь все еще была выбрана), кажется, фокусирует список сразу после закрытия программы MSPaint. Таким образом, я достиг желаемого результата, но я думаю, что, возможно, есть лучшее и более чистое решение.

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Вы можете попытаться запустить дочерний процесс в новом потоке и вызвать process.WaitForExit() после его запуска. Затем, после закрытия дочернего процесса, вы можете сфокусировать свое приложение, используя Dispatcher, поскольку текущий поток не является потоком пользовательского интерфейса.

var process = Process.Start(@"C:\Windows\system32\mspaint.exe");
process.WaitForExit();
Dispatcher.Invoke(() => MainWindow.Current.MakeFocus()); // sample line

Ваше главное окно должно иметь статическое свойство Current, и оно должно быть установлено при запуске вашего основного приложения.

0 голосов
/ 18 января 2019

Фокус - это забота о взгляде.

Таким образом, прямой подход будет состоять в том, чтобы иметь любую модель / службу, которую ваш Process.Start вызывает событие при выходе из процесса, чтобы виртуальная машина подобрала его и по очереди подняла событие, и, наконец, вид реагирует, устанавливая фокус.

В качестве альтернативы, виртуальная машина может установить свойство, скажем CurrentlyInExternalApplication, которое при значении false вышеупомянутым событием вызовет срабатывание триггера (аналогичного существующему).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...