这个有点诡异。从 wpf 的主窗口(单击按钮),我正在创建另一个 STA 线程,其中我正在显示一个自定义窗口。此自定义窗口应用了一种使用 shell 中的 WindowChrome 类的样式。调用 Show() 方法时出现异常。
无法跨线程访问可冻结的“System.Windows.Shell.WindowChrome”,因为它无法被冻结。
如果我删除 WindowChrome 设置器,一切正常。我错过了什么?
我已经尝试将窗口镶边标记为冻结,但徒劳无功!
可在此处获得源的副本。
更新: 忘了提到在样式上添加 x:Shared="False" 似乎可以解决问题,但我不知道为什么!这会导致任何性能瓶颈吗?
MainWindow.xaml:
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication7"
Title="MainWindow"
Height="350"
Width="525" Style="{StaticResource ResourceKey=WindowStyle}">
<Grid>
<Button Content="Open another window please..."
Click="Button_Click" />
</Grid>
</Window>
MainWindow.xaml.cs:
using System.Threading;
using System.Windows;
namespace WpfApplication7
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread windowThread = new Thread(new ThreadStart(() =>
{
Window customWindow = new BackgroundWindow();
customWindow.Closed += (s, a) => System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvokeShutdown(System.Windows.Threading.DispatcherPriority.Background);
customWindow.Show();
System.Windows.Threading.Dispatcher.Run();
}));
windowThread.IsBackground = true;
windowThread.SetApartmentState(ApartmentState.STA);
windowThread.Start();
}
}
}
背景窗口.xaml:
<Window x:Class="WpfApplication7.BackgroundWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication7"
Title="BackgroundWindow"
WindowStartupLocation="CenterScreen"
Style="{StaticResource ResourceKey=WindowStyle}">
</Window>
WindowStyle.xaml(与 App.xaml 合并
<!-- Setting x:Shared=False will solve the cross threaded exception -->
<Style x:Key="WindowStyle"
TargetType="{x:Type Window}">
<Setter Property="Padding"
Value="5,5,5,5" />
<Setter Property="BorderBrush"
Value="Black" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="44"
GlassFrameThickness="-1"
CornerRadius="0,0,0,0" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="{TemplateBinding Property=Background}"
BorderBrush="{TemplateBinding Property=BorderBrush}"
BorderThickness="{TemplateBinding Property=BorderThickness}">
<Grid Background="{TemplateBinding Property=Background}"
UseLayoutRounding="True"
SnapsToDevicePixels="True">
<Grid.RowDefinitions>
<!-- Window Controls -->
<RowDefinition Height="44" />
<!-- Content -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel x:Name="PART_DragPanel"
Grid.Row="0"
Background="Black">
<Button x:Name="PART_CloseButton"
DockPanel.Dock="Right"
HorizontalAlignment="Right"
Margin="3,8,8,8"
WindowChrome.IsHitTestVisibleInChrome="True"
Width="20"
Height="20" />
<Button x:Name="PART_RestoreButton"
DockPanel.Dock="Right"
HorizontalAlignment="Right"
Margin="3,8,3,8"
Visibility="Collapsed"
WindowChrome.IsHitTestVisibleInChrome="True"
Width="20"
Height="20" />
<Button x:Name="PART_MinimizeButton"
DockPanel.Dock="Right"
HorizontalAlignment="Right"
Margin="3,8,3,8"
Visibility="Collapsed"
WindowChrome.IsHitTestVisibleInChrome="True"
Width="20"
Height="20" />
<TextBlock x:Name="PART_Title"
DockPanel.Dock="Left"
Margin="8,8,8,8"
Text="{TemplateBinding Property=Title}"
IsHitTestVisible="False"
WindowChrome.IsHitTestVisibleInChrome="True" />
</DockPanel>
<Border x:Name="contentBorder"
Grid.Row="1"
Padding="{TemplateBinding Property=Padding}">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode"
Value="CanMinimize">
<Setter TargetName="PART_MinimizeButton"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="ResizeMode"
Value="NoResize">
<Setter TargetName="PART_RestoreButton"
Property="Visibility"
Value="Collapsed" />
<Setter TargetName="PART_MinimizeButton"
Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="ResizeMode"
Value="CanResize">
<Setter TargetName="PART_RestoreButton"
Property="Visibility"
Value="Visible" />
<Setter TargetName="PART_MinimizeButton"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter TargetName="PART_RestoreButton"
Property="Visibility"
Value="Visible" />
<Setter TargetName="PART_MinimizeButton"
Property="Visibility"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="ResizeMode"
Value="CanResize">
<Setter Property="WindowChrome.ResizeBorderThickness"
Value="5,5,5,5" />
</Trigger>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter Property="WindowChrome.ResizeBorderThickness"
Value="5,5,5,5" />
</Trigger>
<Trigger Property="ResizeMode"
Value="NoResize">
<Setter Property="WindowChrome.ResizeBorderThickness"
Value="0,0,0,0" />
</Trigger>
</Style.Triggers>
</Style>