Reputation: 53
My app has a Window and I put a frame with page into a grid. Than in Page1.cs I start thread with "while". After execute while window with page must be closed.
I can't use this method Application.Current.Shutdown()
Because this closes all windows, so if I have in my app a few windows after this method all windows will be closed.
I thought about using MVVM but I don't know how.
I want to close one Window from thread on Page.(for example in method update()
)
MainWindow.xaml
<Windowx:Class="WpfApplication1.MainWindow"
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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Frame Source "Page1.xaml">
</Frame>
</Grid>
</Window>
Code Page1.xaml
<Page x:Class="WpfApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Page1">
<Grid>
</Grid>
</Page>
Than I start thread in Page1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace WpfApplication1
{
///
/// Interaction logic for Page1.xaml
///
public partial class Page1 : Page
{
bool isTrue = false;
int i;
private MainWindow vm = new MainWindow();
public Page1()
{
InitializeComponent();
Thread thread = null;
thread = new Thread(() => update());
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
}
void update()
{
while (i<50000)
{
i++;
}
***//How I can close window from this place***
Application.Current.MainWindow.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(Application.Current.MainWindow.Close)); // this don't work
}
}
}
Upvotes: 3
Views: 1643
Reputation: 21999
You have access to vm
(or page) to close. E.g.:
vm.Dispatcher.Invoke(() => vm.Close());
From other thought I think this line is your problem
private MainWindow vm = new MainWindow();
If you create here another instance of MainWindow, then obviously vm
is useless and then you have to do it in very similar to yours way:
Application.Current.MainWindow.Dispatcher.Invoke(() =>
{
Application.Current.MainWindow.Close();
});
I've to try to see the problem, which is access to dispatcher of main window.
This is working solution (using UserControl
, shouldn't matter):
public partial class UserControl1 : UserControl
{
private Dispatcher _dispatcher; // store dispatcher when constructor is called
public UserControl1()
{
InitializeComponent();
_dispatcher = Dispatcher;
var thread = new Thread(() => update());
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
}
void update()
{
// simulate some work
Thread.Sleep(1000);
// close
_dispatcher.Invoke(() => Application.Current.MainWindow.Close());
}
}
Upvotes: 2