Use*_*621 7 c# wpf .net-4.0 resourcedictionary
当我尝试WindowStartupLocation通过a Setter内设置属性时ResourceDictionary,我得到一个XamlParseException:
'Set property'System.Windows.Setter.Property'引发了异常.' 行号'x'和行位置'y'.
内部异常是ArgumentNullException:
值不能为空.参数名称:property.
我在资源字典中的风格是:
<Style TargetType="Window" x:Key="WindowStyle">
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="ResizeMode" Value="CanMinimize" />
<Setter Property="WindowStartupLocation" Value="CenterOwner" />
</Style>
Run Code Online (Sandbox Code Playgroud)
问题不在于使用ResourceDictionary,因为当我删除它时WindowStartupLocation,其他两个属性(SizeToContent和ResizeMode)在引用样式的窗口上按预期设置:
<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>
Run Code Online (Sandbox Code Playgroud)
有没有遇到过这个?它是WPF的错误/限制吗?
PS我知道这个问题类似于资源字典中的Window Startup Location,但是在其他问题中没有提供足够的信息,后来仍未解决.
And*_*nes 11
问题是WindowStartupLocation不是DependencyProperty,因此您无法在样式设置器中设置它.看看ILSpy,Setter打来电话
CheckValidProperty(DependencyProperty property)
Run Code Online (Sandbox Code Playgroud)
并抛出NullArgumentException.
由于WindowStartupLocation只是一个CLR属性,因此无法以这种方式设置.
Edit:回应评论.你仍然可以使用ResourceDictionary:
<Application.Resources>
<ResourceDictionary>
<Style x:Key="WindowStyle" TargetType="Window">
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="ResizeMode" Value="CanMinimize" />
</Style>
<WindowStartupLocation x:Key="WSL">CenterOwner</WindowStartupLocation>
</ResourceDictionary>
</Application.Resources>
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="{StaticResource WSL}"
Style="{StaticResource WindowStyle}" />
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在样式setter中只能指定依赖属性.有两种方法可以解决这个问题:
继承类Window,并使用依赖项属性创建您的类WindowStartupLocation
根据WindowStartupLocationPropertyChanged 创建附加属性类型并定义逻辑
第一种方法很麻烦,因为有必要为一个属性重新定义类.第二种方法是首选,并将附加行为,但我会打电话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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用示例:
<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>
Run Code Online (Sandbox Code Playgroud)