2014-12-04 2 views
0

ОК, следующая проблема:Позиционирование и максимизация окна, которое выполняется в фоновой задаче

У меня есть окна на 10 экранах, которые находятся на одном ПК. Некоторые из них должны работать в фоновых задачах. Его WPF-приложение, но для размещения на экране и т. Д., Я использую некоторые части WinForms. Для этого я использую следующие строки:

foreach (List<string> myStrings in Screen.AllScreens.Select(myScreen => _xml.GetScreenConfigs(i))) 
{ 
    Thread newWindowThread = new Thread(() => 
    { 
    Marketing myMarketing = new Marketing(i, myStrings[0]); 
    myMarketing.Show(); 
    Dispatcher.Run(); 
    }); 
    newWindowThread.SetApartmentState(ApartmentState.STA); 
    newWindowThread.IsBackground = true; 
    newWindowThread.Start(); 
} 

и внутри этого окна я использую следующие для его размещения:

[DllImport("user32.dll")] 
private static extern IntPtr GetActiveWindow(); 
... 
Left = Convert.ToInt32(screenArray[screenNumber].Bounds.Left); 
Top = Convert.ToInt32(screenArray[screenNumber].Bounds.Top); 
var active = GetActiveWindow(); 
var singleOrDefault = Application.Current.Windows.OfType<Window>() 
    .SingleOrDefault(window => new WindowInteropHelper(window).Handle == active); 
if (singleOrDefault == null) return; 
singleOrDefault.Title = "Monitor" + screenNumber; 
singleOrDefault.Name = "Monitor" + screenNumber; 
singleOrDefault.WindowState = WindowState.Maximized; 

Но когда я добираюсь до «вар SingleOrDefault» -линии, я получаю что он не может изменить объект Application.Current.Windows, потому что он принадлежит другому потоку. Итак, мой вопрос:

«Что я могу сделать, чтобы использовать это окно в другом потоке И разместить и максимизировать его?»

+0

Вы уверены, что вам нужно несколько потоков пользовательского интерфейса? Почему просто не использовать один поток пользовательского интерфейса для отображения результатов фоновых операций? – Dennis

+0

Да, потому что есть элемент управления WebBrowser, который выполняется несколько раз, и когда я использую его со вспышкой (и мне нужно использовать флеш-память, нет никакого способа обойти ее), после того, как 3 элемента управления будут опускаться на колени, когда все они работают на той же теме. –

+0

Как я протестировал, коллекция (Application.Current.Windows) регистрирует только окна в основном потоке, вы не можете получить из него свои не связанные с ним потоки. Вы пытаетесь найти активный из большого количества окон и максимизировать его? – Eben

ответ

0

1) Вы писали: и внутри этого окна я использую следующие для его размещения: ... Application.Current.Windows.OfType<Window>..

Вы не можете работать с Interop внутри задач. Поместите его в свое «главное окно». Это объясняет исключение потока.

2) Вы можете получить другое исключение потока, если вы не используете диспетчер окон при изменении UIElemetns. Такова идея ответа от «Капитана». Но TitleName и Windowstate, похоже, не зависят от диспетчера, так как это должны быть реквизиты win32.

+0

Да, но как я мог максимизировать окно маркетинга изнутри App.xaml.cs? –

+0

Вам не нужно. Вы даете нам знать: все это происходит внутри «private void MarketingLoaded (отправитель объекта, RoutedEventArgs e)», почему бы не использовать отправителя, поскольку распространено, что загруженный элемент («маркетинговое» окно) является отправителем события? Я не знаю вашего общего кода, поэтому со своей стороны попробуйте что-то вроде: (отправитель в качестве MarketingWIndow) .WindowState = WindowState.Maximized – deafjeff

+0

Я не хотел спамить эту тему, поэтому, пожалуйста, посмотрите здесь полный код, который устанавливает для этого вопрос: http://pastebin.com/s2gPTVSh –

0

При настройке или получении свойства элемента пользовательского интерфейса вы должны вызвать код в потоке Диспетчера элемента.

Короче, попробуйте следующее:

Application.Current.Dispatcher.Invoke(() => 
{ 
    var singleOrDefault = Application.Current.Windows.OfType<Window>() 
      .SingleOrDefault(window => new WindowInteropHelper(window).Handle == active); 
    if (singleOrDefault == null) return; 
    singleOrDefault.Title = "Monitor" + screenNumber; 
    singleOrDefault.Name = "Monitor" + screenNumber; 
    singleOrDefault.WindowState = WindowState.Maximized; 
}); 

Надеется, что это помогает ...

+0

singleOrDefault нельзя использовать, потому что при объявлении я получаю сообщение об ошибке. Я даже не могу использовать строку: var singleOrDefault = Application.Current.Windows.OfType () .SingleOrDefault (window => new WindowInteropHelper (window) .Handle == active); –

+0

Затем обернуть весь блок под Dispatcher.Invoke Начиная с вар SingleOrDefault = Application.Current.Windows.OfType Я отредактировал мой ответ – Captain

+0

я написал это так, но техника его подводит какой-либо прогресс. та же ошибка: Dispatcher.Invoke (() => { вар SingleOrDefault = Application.Current.Windows.OfType () .SingleOrDefault (Окно => новый WindowInteropHelper (окно) .Handle == активный); .. .}); –

0

Хорошо, я получил (после многих попыток и ошибок) небольшое решение одной из проблем: Очистить все после Left = ... и Top = ... и заполнить WindowState = WindowState.Maximized; затем он максимизируется. Таким образом, остается только одна проблема: Иногда (не каждый запуск) приложение запускается при запуске в строке «InitializeComponent();» внутри Marketing.xaml.cs, а затем снова все работает нормально. Иногда с исключением null-reference-exception, и иногда он говорит, что уже есть компонент, объявленный с этим именем. Кто-то идея здесь, что это могло быть? Должно быть, нужно что-то сделать с помощью потоковой передачи, потому что в первый раз я получаю эти ошибки.

[edit] Я нашел его: я должен использовать lock(), поэтому теперь мне нужно только выяснить, как его использовать. У кого-то есть опыт?

0

Хорошо, есть ответ, который я искал почти два дня:

Для Максимизация: Очистить все после Left = ... и Top = ... и заполнить в WindowState = WindowState.Maximized; то он максимизируется.

Для ExceptionErrors: Поместите static readonly object _locker = new object(); внутри называемого окна и lock (_locker) { InitializeComponent(); }

внутри windowcall. Спасибо за всю помощь, я проголосую за все ваши сообщения, но у меня нет такой репутации.