XAML WPF 中 {x:Static} 和 {StaticResource} 的区别

mar*_*n36 1 wpf xaml

是有什么区别{x:Static}{StaticResource}WPF 的 XAML 代码中?

例如:

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={StaticResource BoolInverseConverter}}">
Run Code Online (Sandbox Code Playgroud)

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={x:Static BoolInverseConverter}}">
Run Code Online (Sandbox Code Playgroud)

我什么时候应该使用其中一个?

Bio*_*ode 5

两者都是标记扩展。

x:Static用于引用静态属性,该属性在运行时不会更改。这适用于枚举、常量、static属性以及字段。
这意味着您的第二个代码示例是错误的,因为您不能引用类而只能引用属性。鉴于这BoolInverseConverter是类的static属性Converters,正确的代码如下所示:

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={x:Static Converters.BoolInverseConverter}}">
Run Code Online (Sandbox Code Playgroud)

StaticResource并不意味着资源是static在可访问性方面,而是在资源查找方面。它是指示 XAML 解析器查找资源树以查找预定义实例的标记扩展。
一样DynamicResource。唯一的区别是StaticResource指示 XAML 解析器在编译时解析对资源的引用,而DynamicResource让 XAML 解析器创建一个表达式,该表达式将在运行时(延迟)进行评估。DynamicResource因此在运行时解析资源。

以下代码片段显示了 XAML 解析器如何通过资源树查找来引用资源(转换器)。由于使用了 XAML 标记扩展StaticResource,因此查找是静态的。这意味着一旦找到资源,就不能被另一个实例替换。而且,如果在编译时未定义实例,应用程序将崩溃,抛出一个StaticResourceExtension. 如果x:key运行时背后的资源发生变化,引用将不会更新(静态):

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={StaticResource BoolInverseConverter}}">
Run Code Online (Sandbox Code Playgroud)

下一个代码片段再次显示了 XAML 解析器如何通过资源树查找来引用资源(转换器)。但是这次使用了DynamicResource标记扩展,让查找变得动态。这意味着将在运行时查找资源。并且每次特定的资源x:Key发生变化时,例如 a Brush,引用实例将相应地更新(动态):

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={DynamicResource BoolInverseConverter}}">
Run Code Online (Sandbox Code Playgroud)

另一个代码片段显示了如何使用标记扩展引用一个实例,该实例不是资源,而是类中static定义的属性:Convertersx:static

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={x:Static Converters.BoolInverseConverter}}">
Run Code Online (Sandbox Code Playgroud)

最后一个代码片段显示了x:Static标记扩展的另一个用例。这次它用于引用枚举值 ( enum) 并将Visibility属性设置为枚举值Visibility

<StackPanel Visibility="{x:Static Visibility.Collapsed}">
Run Code Online (Sandbox Code Playgroud)