Блокировка запуска WPF Dialog из другого потока - PullRequest
0 голосов
/ 30 мая 2019

Мы хотим создать и запустить модальное диалоговое окно над главным окном.Этот процесс инициируется из другого потока - по какой-то причине.Этот другой поток вызывает метод execute - и должен быть заблокирован, пока диалоговое окно не закроется.Вопрос - как?В этом коде выполнение не будет заблокировано.Вызов Join () также не работает должным образом.

public void Execute()
{
    Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
    newWindowThread.SetApartmentState(ApartmentState.STA);
    newWindowThread.IsBackground = true;
    newWindowThread.Start();
    // newWindowThread.Join();
}


private void ThreadStartingPoint()
{
    this.ParameterDialog = new ParameterDialog();
    this.ParameterDialog.ShowDialog();
    System.Windows.Threading.Dispatcher.Run();
}

Есть идеи, как реализовать это поведение?Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Вы должны выключить диспетчер, когда диалоговое окно закрыто:

public void Execute()
{
    Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
    newWindowThread.SetApartmentState(ApartmentState.STA);
    newWindowThread.IsBackground = true;
    newWindowThread.Start();
    newWindowThread.Join();
}

private void ThreadStartingPoint()
{
    this.ParameterDialog = new ParameterDialog();
    this.ParameterDialog.Closed += ParameterDialog_Closed;
    this.ParameterDialog.ShowDialog();
    System.Windows.Threading.Dispatcher.Run();
}

private void ParameterDialog_Closed(object sender, EventArgs e)
{
    this.ParameterDialog.Closed -= ParameterDialog_Closed;
    Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
}
1 голос
/ 30 мая 2019

Не зная, как работает вся ваша установка, вот быстрый пример того, как использовать Dispatcher для взаимодействия со слоем пользовательского интерфейса из отдельного потока.Я использовал примеры из библиотеки Microsoft wpf здесь в качестве отправной точки.Я удалил часть кода, который неприменим.

MainWindow.xaml.cs

 public partial class MainWindow : Window
 {
    public delegate void NextPrimeDelegate();

    private bool _continueCalculating;

    private Action MyCallback = () => 
    {
        //****Carry out your Code (Execute) Here****
        var myPopup = new PopUp();
        myPopup.ShowDialog();
    };
    public MainWindow()
    {
        InitializeComponent();
    }

    private void StartOrStop(object sender, EventArgs e)
    {
        if (_continueCalculating)
        {
            _continueCalculating = false;
            startStopButton.Content = "Resume";
        }
        else
        {
            _continueCalculating = true;
            startStopButton.Content = "Stop";
            startStopButton.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal,
                new NextPrimeDelegate(MyCallback));
        }
    }
}

MyPopUp.xaml

<Window x:Class="SingleThreadedApplication.PopUp"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SingleThreadedApplication"
    mc:Ignorable="d"
    Title="PopUp" Height="200" Width="300">
<Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Close"
                    Executed="CloseCommandHandler"/>
</Window.CommandBindings>

<Grid>
    <TextBlock Text="My Popup" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <Button Content="Close" HorizontalAlignment="Right" VerticalAlignment="Bottom" Command="ApplicationCommands.Close"/>
</Grid>

Добавьте этот метод в PopUp.xaml.cs

private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
   this.Close();
}

Это, мы надеемся, может дать вам отправную точку для взаимодействия со слоем пользовательского интерфейса через различные потоки.

...