How to Set and Restore the Value of WPF Dependency Properties While Preserving All Original Styles, Bindings, and User Settings

How to Set and Restore the Value of WPF Dependency Properties While Preserving All Original Styles, Bindings, and User Settings

Back up some properties of a WPF control, perform some magical operations, and then restore those properties.

Last updated 11/9/2021 10:08 AM
吕毅
4 min read
Category
WPF
Tags
.NET WPF

Backing up some properties of a WPF control, performing some magical operations, and then restoring these properties. How common an operation! Yet, how to back them up is a question worth studying. Direct assignment? You must not have encountered certain pitfalls.

Contents

  • Scenario and Problem
  • Solution and Principle
  • Extension

Scenario and Problem

Now, let's imagine a scenario (for coding convenience):

  1. There is a window with some style properties set.
  2. Now, the window needs to be set to full screen, which requires modifying some original properties (the built-in setting in WPF has bugs; I'll write another blog to explain).
  3. After exiting full screen, those modified properties must be "perfectly" restored.

A common way to write this might be:

private Window _window;
private WindowStyle _oldStyle;

private void OnEnterFullScreen()
{
    _oldStyle = _window.WindowStyle;
    _window.WindowStyle = WindowStyle.None;
}

private void OnExitFullScreen()
{
    _window.WindowStyle = _oldStyle;
}

However:

  • What if someone has set a dynamic style on WindowStyle? — Then it will no longer be dynamic (because the style value is overwritten).
  • What if someone has set a binding on WindowStyle? — Then it will no longer take effect (because the binding is overwritten by you).

Solution and Principle

Since many introductory WPF books mention the precedence mechanism of dependency properties, you should basically know about it. If you don't, go here immediately: Dependency Property Value Precedence - WPF Microsoft Docs.

The precedence is: Coercion > Animations > Local Value > Template > Implicit Style > Style Triggers > Template Triggers > Style > Default Style > Property Value Inheritance > Metadata Default.

When you assign a value directly in XAML or C# code, you are setting a "local value". Therefore, if a local value is set, all lower-priority styles naturally become invalid.

What about bindings? Bindings do not exist in the dependency property priority list. Bindings are actually implemented through "local values": a binding expression is set into the local value, and when the value is needed, ProvideValue provides it. So, if you set a local value again, the binding's setting is overwritten.

But SetCurrentValue is exactly designed for this!

SetCurrentValue is designed to set the current value of a property without changing any existing value of the dependency property.

_window.SetCurrentValue(Window.WindowStyleProperty, WindowStyle.None);

Then, to revert the changes made by SetCurrentValue, you can restore all set values of this dependency property:

_window.InvalidateProperty(Window.WindowStyleProperty);

Note that it's not ClearValue, which clears the local value.

However, one more thing: if the binding changes while you apply SetCurrentValue, the assignment will not make the binding take effect immediately, so you need to manually force the binding to update its value:

BindingOperations.GetBindingExpression(_window, Window.WindowStyleProperty)?.UpdateTarget();

Therefore, combining everything, the initial code will be updated to:

private Window _window;

private void OnEnterFullScreen()
{
    _window.SetCurrentValue(Window.WindowStyleProperty, WindowStyle.None);
}

private void OnExitFullScreen()
{
    _window.InvalidateProperty(Window.WindowStyleProperty);
    BindingOperations.GetBindingExpression(_window, Window.WindowStyleProperty)?.UpdateTarget();
}

Extension

To make the code more generic:

static void ApplyTempProperty(DependencyObject d, DependencyProperty dp, object tempValue)
{
    d?.SetCurrentValue(dp, tempValue);
}

static void RestoreProperty(DependencyObject d, DependencyProperty dp)
{
    d.InvalidateProperty(dp);
    BindingOperations.GetBindingExpression(d, dp)?.UpdateTarget();
}

This article will be updated frequently. Please read the original article: https://blog.walterlv.com/post/change-and-restore-wpf-dependency-value-without-disabling-the-declared-use-of-the-property.html to avoid misleading from outdated and incorrect knowledge, and to have a better reading experience.

If you want to keep reading my latest blog, please click RSS subscription, or go to CSDN to follow my homepage.

Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. You are free to share, adapt, and republish, but must retain the author's attribution (Lü Yi, including link: https://blog.walterlv.com ), not for commercial purposes, and must distribute any modifications under the same license. If you have any questions, please contact me (walter.lv@qq.com).

Keep Exploring

Related Reading

More Articles
Same category / Same tag 9/13/2025

Migration Series from WPF to Avalonia: Why I Must Migrate My WPF Application to Avalonia

In the past few years, our host computer software has mainly been developed using WPF and WinForm . These technologies work well on the Windows platform and have accompanied us from small-scale trial production to the current stage of large-scale delivery. However, with business development and changes in customer requirements, the single Windows technology stack has gradually become a hurdle we must overcome.

Continue Reading
Same category / Same tag 1/26/2025

Implementing Internationalization in WPF Using Custom XML Files

This article details the method of implementing internationalization in WPF applications using custom XML files, including installing the necessary NuGet packages, dynamically retrieving the language list, dynamically switching languages, using translated strings in code and XAML interfaces, and provides a source code link to help developers easily achieve internationalization in WPF applications.

Continue Reading