Binding MaskedText property of Telerik Silverlight RadMaskedTextBox

If you have used Telerik’s RadMaskedTextBox for Silverlight most probably in some cases you have needed to bind in TwoWay mode the MaskedText property of the control (for example for Phones, SSNs, etc. that need to be saved with the punctuation). And most probably you were surprised that you cannot do this because the MaskedText property is readonly. We’ve asked Telerik whether they are considering to implement such a functionality, but currently there is no definite answer to this.

So here is how to extend they RadMaskedTextBox so you can do your work:

VB:

Imports System.Windows.Data
Imports Telerik.Windows

Public Class RadMaskedTextBoxExtended
    Inherits Telerik.Windows.Controls.RadMaskedTextBox

    Private m_bIsValueChangingIn As Boolean = False

#Region " Dependency Property "
    Public Shared ReadOnly ValueMaskProperty As DependencyProperty = _
    DependencyProperty.Register("ValueMask" _
                                , GetType(String) _
                                , GetType(RadMaskedTextBoxExtended) _
                                , New PropertyMetadata(AddressOf ValueMaskChanged) _
                                )
#End Region

#Region " Constructor "
    Public Sub New()
        MyBase.New()
        AddHandler Me.ValueChanged, AddressOf OnValueChanged
    End Sub
#End Region

#Region " Properties "
    Public Property ValueMask() As String
        Get
            Return CStr(Me.GetValue(ValueMaskProperty))
        End Get
        Set(ByVal value As String)
            Me.SetValue(ValueMaskProperty, value)
        End Set
    End Property

    Public Property IsValueChangingIn() As Boolean
        Get
            Return m_bIsValueChangingIn
        End Get
        Set(ByVal value As Boolean)
            m_bIsValueChangingIn = value
        End Set
    End Property
#End Region

#Region " Change Tracking Events "
    Private Sub OnValueChanged(ByVal sender As Object, ByVal e As RadRoutedEventArgs)
        m_bIsValueChangingIn = True
        Me.ValueMask = Me.MaskedText
        Dim oBindingExpression As BindingExpression = Me.GetBindingExpression(ValueMaskProperty)

        If oBindingExpression IsNot Nothing Then
            oBindingExpression.UpdateSource()
        End If
        m_bIsValueChangingIn = False
    End Sub

    Private Shared Sub ValueMaskChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
        Dim txtRadMaskedTextBoxExtended As RadMaskedTextBoxExtended = CType(d, RadMaskedTextBoxExtended)

        If Not Equals(e.OldValue, e.NewValue) _
        AndAlso Not txtRadMaskedTextBoxExtended.IsValueChangingIn _
        Then
            txtRadMaskedTextBoxExtended.Value = e.NewValue
        End If
    End Sub
#End Region

End Class

Then instead of using their control, just use RadMaskedTextBoxExtended and use the ValueMask property to bind the business object property that must contain the masked text.

This worked quite well in my case 🙂
Enjoy!

Binding IsChecked property of RadioButton in WPF

If you have tried to bind the RadioButton’s IsChecked property in WPF to an object, you have most likely experienced the following problem: In OneWay bindings it works great. But if you have more than one RadioButtons binded TwoWay and you click on an unchecked one, you were expecting that the object to which the previously checked RadioButton was binded to receive the value of False. But you were wrong in your expectations. That’s because for some reasons Microsoft does not obey bindings and does not pass the False value to the DependencyProperty and instead of that they just assign the value False directly to the property, which ruins the binding.

There are many proposed solutions to this around the internet, problem with all those is that they do not work with dynamically generated controls. So since I had to find a way to make this working with dynamic controls, decided to make a wrapper of the real RadioButton which will correctly Bind in two ways. Here is the code for the wrapper:

using System;
using System.IO;
using System.Printing;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using Microsoft.Win32;

namespace Controls
{
    public class RadioButtonExtended : RadioButton
    {
        static bool m_bIsChanging = false;

        public RadioButtonExtended()
        {
            this.Checked += new RoutedEventHandler(RadioButtonExtended_Checked);
            this.Unchecked += new RoutedEventHandler(RadioButtonExtended_Unchecked);
        }

        void RadioButtonExtended_Unchecked(object sender, RoutedEventArgs e)
        {
            if (!m_bIsChanging)
                this.IsCheckedReal = false;
        }

        void RadioButtonExtended_Checked(object sender, RoutedEventArgs e)
        {
            if (!m_bIsChanging)
                this.IsCheckedReal = true;
        }

        public bool? IsCheckedReal
        {
            get { return (bool?)GetValue(IsCheckedRealProperty); }
            set
            {
                SetValue(IsCheckedRealProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for IsCheckedReal. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsCheckedRealProperty =
        DependencyProperty.Register("IsCheckedReal", typeof(bool?), typeof(RadioButtonExtended),
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Journal |
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
        IsCheckedRealChanged));

        public static void IsCheckedRealChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            m_bIsChanging = true;
            ((RadioButtonExtended)d).IsChecked = (bool)e.NewValue;
            m_bIsChanging = false;
        }
    }
}

So now all you have to do is to use the ExtendedRadioButton instead of the built-in one and bind to the IsCheckedReal property instead of the IsChecked one.
Enjoy 🙂