Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF Behavior to Set Control Value to DefaultValue on Visibility Changed

0.00/5 (No votes)
2 May 2018 1  
The tip provides a behavior that will set a control to a default value when the Visibility changes

Introduction

I was doing work where a lot of the functionality in an WPF MVVM project was within the View. Part of the View would change visibility, and when these parts again became visible, they needed to be back to a default value. With this behavior, this functionality can be implemented with a behavior attached to the control.

I had previously done a couple of tips that also reset values on visibility changed. They were behaviors that attacked the control containing a number of ToggleButton/RadioButton/CheckBox controls. On working on these behaviors, I realized that it may be desirable to be able to handle more types of controls, and to be able to set not just bool Type values, but more general values.

Using the Code

Here is the code for the behaviour:

public class DefaultValueOnVisibilityBehavior
{
    private static void OnDefaultValuePropertyChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var element = (FrameworkElement)d;
        element.IsVisibleChanged -= ElementOnIsVisibleChanged;

        element.IsVisibleChanged += ElementOnIsVisibleChanged;
    }

    public static object GetDefaultValue(DependencyObject obj)
    {
        return obj.GetValue(DefaultValueProperty);
    }

    public static void SetDefaultValue(DependencyObject obj, object value)
    {
        obj.SetValue(DefaultValueProperty, value);
    }

    public static readonly DependencyProperty DefaultValueProperty =
        DependencyProperty.RegisterAttached("DefaultValue",
            typeof(object), typeof(DefaultValueOnVisibilityBehavior),
            new PropertyMetadata(OnDefaultValuePropertyChanged));

    private static void ElementOnIsVisibleChanged(object sender,
        DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        FrameworkElement frameworkElement = (FrameworkElement)sender;
        var defaultValue = GetDefaultValue(frameworkElement);
        var defaultValueString = defaultValue.ToString();
        var dependencyObject = (UIElement)sender;

        if (sender is ToggleButton toggleBusson)
            toggleBusson.IsChecked = defaultValueString.ToLower() == "true"
                ? true : defaultValueString.ToLower() == "false"
                ? false : (bool?)null;
        else if (sender is TextBox textBox)
            textBox.Text = defaultValueString;
        else if (sender is ContentControl contentControl)
            contentControl.Content = defaultValue;
    }
}

There is a single DependencyProperty, DefaultValue. This is the value that a DependencyProperty on the control is set to. The changing of this DependencyProperty will cause the OnDefaultValuePropertyChanged event handler to be assigned to the VisibilityChanged event. When the Visibility changes, then the value of the DefaultValue DependencyProperty will be assigned to a DependencyProperty of the control based on the control Type. The following are the DependencyProperty definitions that are affected:

  • CheckBox, ToggleButton, RadioButton: IsChecked DependencyProperty.
  • TextBox: Text DependencyProperty.
  • ContentControl (other than above): Content DependencyProperty.

More can be defined, such as for ListBox, and could add the functionality to select the DependencyProperty that is affected, but I did not need this capability.

Using the Behavior

Here are some simple examples of how to use this behavior:

<RadioButton local:DefaultValueOnVisibilityBehavior.DefaultValue="True"
             Content="RadioButton Two (Default true)" />
<ToggleButton local:DefaultValueOnVisibilityBehavior.DefaultValue="True"
              Content="ToggleButton Two (Default true)"/>
<TextBox Grid.Row="2"
              Grid.Column="1" Margin="5"
              local:DefaultValueOnVisibilityBehavior.DefaultValue
    ="{Binding ElementName=ComboBox,
                               Path=SelectedItem.Content}" />
<RadioButton Grid.Row="3" Margin="5"
             Grid.Column="0"
             Content="RadioButton Four" />
<TextBox Grid.Row="3"
              Grid.Column="1" Margin="5"
          local:DefaultValueOnVisibilityBehavior.DefaultValue="This is the default Value" />

History

  • 05/02/2018: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here