When I attempt to set the WindowStartupLocation
property through a Setter
within a ResourceDictionary
, I get a XamlParseException
:
'Set property 'System.Windows.Setter.Property' threw an exception.' Line number 'x' and line position 'y'.
The inner exception is an ArgumentNullException
:
Value cannot be null. Parameter name: property.
My style within the resource dictionary is:
<Style TargetType="Window" x:Key="WindowStyle">
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="ResizeMode" Value="CanMinimize" />
<Setter Property="WindowStartupLocation" Value="CenterOwner" />
</Style>
The issue is not with the use of the ResourceDictionary
, since when I remove the WindowStartupLocation
, the other two properties (SizeToContent
and ResizeMode
) are set as expected on windows which reference the style:
<Window x:Class="WpfApplication1.MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Style="{DynamicResource WindowStyle}">
<Window.Resources>
<ResourceDictionary Source="MyResourceDictionary.xaml" />
</Window.Resources>
</Window>
Has anyone encountered this? Is it a bug/limitation of WPF?
P.S. I know that this question is similar to Window Startup Location from resource dictionary, but not enough information was provided in the other question which subsequently remained unsolved.
WindowStartupLocation
is a CLR property, this can be seen in ILSpy
:
[DefaultValue(WindowStartupLocation.Manual)]
public WindowStartupLocation WindowStartupLocation
{
get
{
this.VerifyContextAndObjectState();
this.VerifyApiSupported();
return this._windowStartupLocation;
}
set
{
this.VerifyContextAndObjectState();
this.VerifyApiSupported();
if (!Window.IsValidWindowStartupLocation(value))
{
throw new InvalidEnumArgumentException("value", (int)value, typeof(WindowStartupLocation));
}
this._windowStartupLocation = value;
}
}
In the style setters can only be specified dependency property. There are two ways to solve this problem:
inherit class Window
, and create your class with a dependency property WindowStartupLocation
create an attached property type depending WindowStartupLocation
and define the logic in the PropertyChanged
The first method is cumbersome, because it is necessary to redefine the class for one property. The second method is preferred, and will be attached behavior, but I'll call PropertyExtension
.
Here is the complete code:
namespace YourProject.PropertiesExtension
{
public static class WindowExt
{
public static readonly DependencyProperty WindowStartupLocationProperty;
public static void SetWindowStartupLocation(DependencyObject DepObject, WindowStartupLocation value)
{
DepObject.SetValue(WindowStartupLocationProperty, value);
}
public static WindowStartupLocation GetWindowStartupLocation(DependencyObject DepObject)
{
return (WindowStartupLocation)DepObject.GetValue(WindowStartupLocationProperty);
}
static WindowExt()
{
WindowStartupLocationProperty = DependencyProperty.RegisterAttached("WindowStartupLocation",
typeof(WindowStartupLocation),
typeof(WindowExt),
new UIPropertyMetadata(WindowStartupLocation.Manual, OnWindowStartupLocationChanged));
}
private static void OnWindowStartupLocationChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
Window window = sender as Window;
if (window != null)
{
window.WindowStartupLocation = GetWindowStartupLocation(window);
}
}
}
}
Example of using:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:PropertiesExtension="clr-namespace:YourProject.PropertiesExtension">
<Style TargetType="{x:Type Window}">
<Setter Property="PropertiesExtension:WindowExt.WindowStartupLocation" Value="CenterScreen" />
<Setter Property="Width" Value="723" />
<Setter Property="Height" Value="653" />
<Setter Property="Title" Value="MainWindow title string" />
</Style>
</ResourceDictionary>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With