Click here to Skip to main content
15,891,744 members
Articles / Desktop Programming / WPF
Tip/Trick

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

Rate me:
Please Sign up or sign in to vote.
4.60/5 (4 votes)
23 Sep 2015CPOL2 min read 12.8K   5   1
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:

C#
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:

XML
<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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead IGATE
India India
I am currently working as technical lead in IGATE and have total of 8 years of experience in developing .Net technologies such as WPF with PRISM & MEF, C#, Entity Framework and solid background in software development life cycle process such as Agile, Six Sigma and Iterative Process.

Comments and Discussions

 
QuestionNice work Pin
Santhakumar M24-Sep-15 8:06
professionalSanthakumar M24-Sep-15 8:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.