从ResourceDictionary设置WindowStartupLocation会抛出XamlParseException

当我尝试通过ResourceDictionarySetter设置WindowStartupLocation属性时,我得到一个XamlParseException

‘Set property’System.Windows.Setter.Property’抛出exception。’ 行号’x’和行位置’y’。

内部exception是ArgumentNullException

值不能为空。 参数名称:property。

我在资源字典中的风格是:

      

问题不在于使用ResourceDictionary ,因为当我删除WindowStartupLocation ,其他两个属性( SizeToContentResizeMode )在引用样式的窗口上按预期设置:

      

有没有人遇到过这个? 它是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); } } } } 

使用示例: