This one is bit bizarre. From a main window in wpf (on a button click), I am creating another STA Thread where I am showing a custom window. This custom window is applied with a style that uses the WindowChrome class from shell. I get an exception while calling the Show() method.
Cannot access Freezable 'System.Windows.Shell.WindowChrome' across threads because it cannot be frozen.
If I remove the WindowChrome setter, everything works just fine. What am I missing?
I've already tried marking the window chrome as frozen, but in vain!
A copy of the source is available here.
Update: Forgot to mention that adding x:Shared="False" on the style seems to fix the problem, but I do not know why! Will this cause any performance bottlenecks?
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();
}
}
}
BackgroundWindow.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 (merged with the 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>