Difference between {x:Static} and {StaticResource} in XAML WPF

Viewed 1511

What is the difference between {x:Static} and {StaticResource} in the XAML code for WPF?

For example:

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={StaticResource BoolInverseConverter}}">

and

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={x:Static BoolInverseConverter}}">

And when should I use one or the other?

1 Answers

Both are markup extensions.

x:Static is used to reference a static attribute, which won't change during runtime. This applies to enumerations, constants, static properties but also fields.
This means your second code example is wrong as you can't reference a class but only a property. Given that BoolInverseConverter is a static property of the Converters class, the correct code would look like:

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={x:Static Converters.BoolInverseConverter}}">

StaticResource does not mean that the resource is static in terms of accessibility but rather in terms of resource lookup. It's a markup extension that instructs the XAML parser to lookup the resource tree to find a predefined instance.
Same does DynamicResource. The only difference is that StaticResource instructs the XAML parser to resolve the reference to a resource at compile time, whereas DynamicResource let's the XAML parser create an expression instead, that will be evaluated at run time (deferred). DynamicResource therefore resolves the resource at run time.

The following code snippet shows how the resource (the converter) is referenced via resource tree lookup by the XAML parser. Since the XAML markup extension StaticResource is used, the lookup is static. This means once the resource was found, it can't be replaced by another instance. And also if the instance is not defined during compile time, the application will crash, throwing a StaticResourceExtension. In case the resource behind the x:key changes during runtime, the references won't update (static):

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={StaticResource BoolInverseConverter}}">

The next code snippet again shows how the resource (the converter) is referenced via resource tree lookup by the XAML parser. But this time using the DynamicResource markup extension, so that the lookup becomes dynamic. This means the resource will be looked up during runtime. And everytime the resource of the specific x:Key changes e.g., a Brush, the referencing instance will update accordingly (dynamic):

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={DynamicResource BoolInverseConverter}}">

Another code snippet shows how to reference an instance, which is not a resource, but a static property defined in the Converters class, using the x:static markup extension:

<StackPanel IsEnabled="{Binding Model.IsReadOnly, Converter={x:Static Converters.BoolInverseConverter}}">

The last code snippet shows another use case of the x:Static markup extension. This time it's used to reference an enumeration value (enum) and sets the Visibility property to a value of the Visibility enumeration:

<StackPanel Visibility="{x:Static Visibility.Collapsed}">
Related