问题重现:
1、创建一个WPF项目;
2、创建一个Window,添加一个按钮,Click事件中添加如下代码:
Window window = new Window();
window.Show();
window.Activate();
3、创建一个DataGrid,使用自定义模板列,DataTemplate中的控件为一个TextBlock,MouseDown事件同样添加以上代码。
4、鼠标单击按钮和DataGrid中的TextBlock,发现以下区别:
在DataGrid中打开的Window并没有置于最前,而Button中打开的Window正常。且window.Activate();返回值是true,说明执行成功。问题关键在于,window.Activate()执行没有效果。
==========================================================================================
由于项目需求原因,需要能打开多个窗口,不能使用Window.ShowDialog(),也不能使用TopMost = true,这样无法将其他窗口置于最前。另外设置window.Owner之后,无法再windows任务栏通过鼠标单击切换到其他窗口。
部分代码如下:
MainWindow.xaml
<Window x:Class="TestWindowShow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestWindowShow"
Title="MainWindow" Height="229" Width="509">
<Grid>
<StackPanel>
<Button Width="250" Height="30" Content="Create new window" Click="Button_Click"/>
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn Header="header1">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:UserControlButton/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="header2">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:UserControlButton/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.Items>
test
</DataGrid.Items>
</DataGrid>
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn Header="header1">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:UserControlButton1/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="header2">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:UserControlButton1/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.Items>
test
</DataGrid.Items>
</DataGrid>
</StackPanel>
</Grid>
</Window>
using System.Windows;
namespace TestWindowShow
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window window = new Window();
window.Show();
window.Activate();
}
}
}
<UserControl x:Class="TestWindowShow.UserControlButton"
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"
mc:Ignorable="d"
d:DesignHeight="118" d:DesignWidth="330">
<Grid>
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="Create new window from datagrid" MouseDown="TextBlock_MouseDown" TextDecorations="UnderLine"/>
</Grid>
</UserControl>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace TestWindowShow
{
/// <summary>
/// UserControlButton.xaml 的交互逻辑
/// </summary>
public partial class UserControlButton : UserControl
{
public UserControlButton()
{
InitializeComponent();
}
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
Window window = new Window();
window.Show();
window.Activate();
}
}
}
UserControlButton1.xaml
<UserControl x:Class="TestWindowShow.UserControlButton1"
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"
mc:Ignorable="d"
d:DesignHeight="118" d:DesignWidth="330">
<Grid>
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="Create new window from dg dispatcher" MouseDown="TextBlock_MouseDown" TextDecorations="UnderLine"/>
</Grid>
</UserControl>
UserControlButton1.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System;
namespace TestWindowShow
{
/// <summary>
/// UserControlButton1.xaml 的交互逻辑
/// </summary>
public partial class UserControlButton1 : UserControl
{
public UserControlButton1()
{
InitializeComponent();
}
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
Window window = new Window();
window.Show();
window.Activate();
}
}
}
======================================================================================================
解决方法:
参考StackOverFlow (http://stackoverflow.com/questions/7211523/wpf-bring-window-to-front)
解决方法如下:
window.Activate();改成以下代码
this.Dispatcher.BeginInvoke(new Action(delegate
{
window.Activate();
}),System.Windows.Threading.DispatcherPriority.ContextIdle,null);
至于问题出现的原因,目前还没有弄明白,有知道的在下面留言。