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

Applying Reusable Read Only Styles for WPF Controls at Application/User Control Level

0.00/5 (No votes)
23 Sep 2015 2  
This tip describes about applying reusable read-only styles for WPF controls at Application/User Control level

Introduction

Many times, we want to apply read only style to some of WPF controls such as TextBox, CheckBox DataGrid, etc. so that the user cannot change the value but easily view the data. Developer’s immediate thought will go for disabling the control simply. This is because; if we set “IsEnabled” property to false to parent control/element, then all the child controls/elements will also be disabled. But, it is not preferred to go for disabling the controls for the reasons not limited to but includes:

  • User will not able to copy the text from the TextBox
  • Scrollbar will not work hence data will not be viewed fully
  • Expander cannot be expanded or collapsed
  • Overall look and feel is not good from end user perspective

However, we don’t have similar kind of approach available to set read only state hierarchically since not all controls have the “IsReadOnly” property.

Background

Fair knowledge about the following topics is required to understand this article better:

  • Resources & Resource Dictionaries
  • Styles & Triggers
  • Attached properties

Using the Code

Step by Step Procedure

1. Create Attached Property

  1. Create a class similar to ReadOnlyStyleHelper
  2. Create an attached property namely AllowEdit

Refer to the below example:

public class ReadOnlyStyleHelper
    {
        public static readonly DependencyProperty AllowEditProperty = 
        DependencyProperty.RegisterAttached("AllowEdit", typeof(bool), 
        typeof(ReadOnlyStyleHelper), new FrameworkPropertyMetadata(true,FrameworkPropertyMetadataOptions.Inherits));

        public static bool GetAllowEdit(DependencyObject obj)
        {
            return (bool)obj.GetValue(AllowEditProperty);
        }

        public static void SetAllowEdit(DependencyObject obj, bool value)
        {
            obj.SetValue(AllowEditProperty, value);
        }               
    }

Note the parameter “FrameworkPropertyMetadataOptions.Inherits” which is responsible for property inheritance. It means that all child controls will inherit the property.

2. Set Attached Property

  1. Refer to the namespace of the attached property class (which is created in the previous step) in the target user control or window for which read-only style has to be applied.
  2. Set the attached property to top most element. You may use view model binding as well based on requirement.

3. Apply Style for Controls

Write style for controls like TextBox, CheckBox, DataGrid, etc. as below:

<Style TargetType="{x:Type CheckBox}">
        <Style.Triggers>
            <Trigger Property="localUtils:ReadOnlyStyleHelper.AllowEdit" Value="False">
                <Setter Property="IsHitTestVisible" Value="False"/>
                <Setter Property="Focusable" Value="False"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

    <Style TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="localUtils:ReadOnlyStyleHelper.AllowEdit" Value="False">
                <Setter Property="IsReadOnly" Value="True"/>
            </Trigger>
        </Style.Triggers>
    </Style>

Note: Apply key attribute if you want to apply this style to specific controls rather than all instances.

4. Create Resource Dictionary

Create a Resource Dictionary using the above styles.

5. Refer to the Resource Dictionary

Refer or merge the above created resource dictionary in the top most user control, window or even App.Xaml.

Points of Interest

The idea is to go for some attached property as we don’t have read-only property available for all controls. But, it is not necessary to set this property to each and every control, rather set it on the top most control or user-control or even window. Property inheritance can be achieved by WPF’s dependency property mechanism. We should apply read-only style for controls which are interested. Resource dictionary should be created by making use of the styles which need to be referred wherever required.

History

  • 24th September, 2015: 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