Я пишу код WPF / C #, где мне нужно перебрать все мои представления (окна) в моем приложении.Для каждой итерации я открываю окно, делаю снимок экрана окна, затем закрываю окно.
Первая проблема, с которой я столкнулся, заключалась в том, что снимок экрана выполнялся до того, как окно было полностью окрашено.экран.Но этот пост помог мне решить эту проблему.Проблема у меня в том, что она работает нормально, когда я просто открываю одно окно.Но поскольку теперь я запускаю цикл, для обработки каждого окна экран зависает.
Если вы посмотрите на мой код ниже, вы увидите, что я использую DispatcherPriority.ApplicationIdle
для моего DispatcherTimer.Это хорошо работает для одного окна, потому что в конечном итоге приложение станет бездействующим после того, как откроет одно окно.Но очевидно, что application idle
никогда не происходит, когда я начинаю свой цикл.Что, я уверен, объясняет, почему экран зависает, когда я пытаюсь обработать все мои окна в цикле.Как я могу обработать каждое из моих окон независимо?Или найти способ вызывать код захвата экрана после открытия каждого окна?
private void StartCapturing(object sender, EventArgs e)
{
// When opening one view using the next three lines, it works fine, the screen capture occurs when the window is fully painted.
// i = 0;
// m_view = SystemConfigurationComponent.GetView(@"gtcs\gcs\mmc_alarmlist");
// CaptureView(m_view);
// But when I loop all my views, screen freezes.
var allViews = SystemConfigurationComponent.GetAllViews();
foreach (var view in allViews)
{
i++;
m_view = view;
CaptureView(view);
}
}
private void CaptureView(View view)
{
// Call UiLoaded method when UI is loaded and rendered
m_dispatchTimer = new DispatcherTimer(TimeSpan.Zero, DispatcherPriority.ApplicationIdle, UiLoaded, Application.Current.Dispatcher);
// Invoke OpenMimic with highest priority.
Application.Current.Dispatcher.Invoke(new Action(() =>
{
ViewsIntegrationService.OpenMimic(m_view.Uri, string.Empty, string.Empty, 2, null, null);
}), DispatcherPriority.Send, null);
}
/// <summary>
/// Method called when DispatcherTimer when application is idle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void UiLoaded(object sender, EventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.ApplicationIdle,
new Action(() =>
{
// UI thread sometimes does not finish painting the window completely, so we delay the print screen slightly.
Thread.Sleep(3000);
//Dispatcher.Yield(DispatcherPriority.ApplicationIdle);
// Generate print screen and save as Jpeg image file.
using (Bitmap bitmap = new Bitmap(m_view.DefaultWidth, m_view.DefaultHeight + 35))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(m_view.DefaultLeft, m_view.DefaultTop + 130), Point.Empty,
new Size() { Width = m_view.DefaultWidth, Height = m_view.DefaultHeight + 35 });
}
bitmap.Save(@"C:\\temp\\GTCS_PrintScreens\\test" + i++ + ".jpg", ImageFormat.Jpeg);
//bitmap.Save(view.WindowTitle.Replace(" ", string.Empty).Replace("'", string.Empty) + ".jpg", ImageFormat.Jpeg);
// Stop dispatcher timer, otherwise it will generate a lot of print screens.
m_dispatchTimer.Stop();
// Close mimic.
m_alsMimic = m_mimicsManager.Mimics.SingleOrDefault(m => m.Path == m_view.Uri);
ViewsIntegrationService.CloseView(new AlstomGuiMimicImpl(m_mimicsManager, m_alsMimic));
}
}));
}