定位并最大化在后台任务中运行的窗口

时间:2014-12-04 08:51:20

标签: c# wpf multithreading winforms wpf-controls

好的,问题如下:

我在一台PC上有多达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;

但是当我到达“var singleOrDefault”-line时,我得到一个错误,说它无法更改对象Application.Current.Windows,因为它由另一个线程拥有。 所以我的问题如下:

“我能做什么,在不同的线程中使用此窗口并定位并最大化它?”

4 个答案:

答案 0 :(得分:0)

设置或获取UI元素的属性时,必须在元素的Dispatcher线程上调用代码。

简而言之,试试这个:

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;
});

希望这会有所帮助......

答案 1 :(得分:0)

1) 你写了: 在这个窗口中我使用以下内容来定位它: ... Application.Current.Windows.OfType<Window>..

您无法从任务内部操作Interop。把它放在你的&#34;主人&#34;窗口。这解释了线程异常。

2) 如果您在修改UIElemetns时未使用Windows的调度程序,则可能会遇到另一个线程异常。这就是&#34; Captain&#34;的回答。 但是Title NameWindowstate似乎不依赖于调度员,因为这些应该是win32道具。

答案 2 :(得分:0)

好的,我(经过多次尝试和错误)得到了一个解决其中一个问题的方法: 在Left = ...和Top = ...之后清除所有内容并填写WindowState = WindowState.Maximized; 然后它最大化。 所以只剩下一个问题: 有时(不是每次启动)应用程序在启动时崩溃&#34; InitializeComponent();&#34;在Marketing.xaml.cs中,然后有时候一切正常。有时使用null-reference-exception,有时它表示已经有一个使用此名称声明的组件。 有人在这里想到那可能是什么?必须要对线程做一些事情,因为这是我第一次遇到这些错误。

[编辑] 我发现它:我必须使用lock(),所以现在我只需要找出如何使用它。有人有经验吗?

答案 3 :(得分:0)

好的,我搜索了近两天的答案:

最大化: 在Left = ...和Top = ...之后清除所有内容并填写WindowState = WindowState.Maximized;然后它最大化。

对于异常错误: 将static readonly object _locker = new object();放入被调用窗口和 lock (_locker) { InitializeComponent(); }

在windowcall里面。 感谢所有的帮助,我会投票给你所有的帖子,但我没有这样的声誉。

相关问题