从ResourceDictionary设置WindowStartupLocation会抛出XamlParseException
当我尝试通过ResourceDictionary
的Setter
设置WindowStartupLocation
属性时,我得到一个XamlParseException
:
‘Set property’System.Windows.Setter.Property’抛出exception。’ 行号’x’和行位置’y’。
内部exception是ArgumentNullException
:
值不能为空。 参数名称:property。
我在资源字典中的风格是:
问题不在于使用ResourceDictionary
,因为当我删除WindowStartupLocation
,其他两个属性( SizeToContent
和ResizeMode
)在引用样式的窗口上按预期设置:
有没有人遇到过这个? 它是WPF的错误/限制吗?
PS我知道这个问题类似于资源字典中的Window Startup Location ,但在另一个问题中没有提供足够的信息,后来仍未解决。
问题是WindowStartupLocation不是DependencyProperty,因此您无法在样式设置器中设置它。 看着ILSpy,Setter打来电话
CheckValidProperty(DependencyProperty property)
并抛出NullArgumentException。
由于WindowStartupLocation只是一个CLR属性,因此无法以这种方式设置。
Edit:
回复评论。 您仍然可以使用ResourceDictionary
:
CenterOwner
WindowStartupLocation
是一个CLR属性,可以在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; } }
在样式setter中只能指定依赖属性。 有两种方法可以解决这个问题:
-
inheritance类
Window
,并使用依赖项属性WindowStartupLocation
创建您的类 -
根据
WindowStartupLocation
创建附加属性类型,并在PropertyChanged中定义逻辑
第一种方法很麻烦,因为有必要为一个属性重新定义类。 第二种方法是首选的,并且将附加行为,但我将调用PropertyExtension
。
这是完整的代码:
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); } } } }
使用示例: