RadMaskedEditBox with nullable value

4 posts, 0 answers
  1. Michael
    Michael avatar
    41 posts
    Member since:
    Oct 2010

    Posted 13 May Link to this post

    Hi,

    I can't seem to figure out the right control to use for my task.  I tried RadMaskedEditBox with all type of masking type and RadSpinEditor, but neither can get me what I need.  Here is what I need:

    1. This control must allow to enter only numeric values.

    2. This control has to be binded to a nullable integer. 

    3. This control need to allow me to delete the value leaving it blank, which should assign null to the binded property.  Vice versa, if I set value of the binded property to null, then control should not contain any values.

    Any suggestions?

    Thank you in advance.

     

  2. Dimitar
    Admin
    Dimitar avatar
    1404 posts

    Posted 17 May Link to this post

    Hi Michael,

    Thank you for writing.

    To achieve this you can use a standard mask. In addition, you will need to handle the Parse event and handle the null values. Here is a complete example for this:
    public partial class Form1 : Form
    {
        MyData data = new MyData() { Value = 300 };
        public Form1()
        {
            InitializeComponent();
     
            radMaskedEditBox1.MaskType = Telerik.WinControls.UI.MaskType.Standard;
            radMaskedEditBox1.Mask = "999";
             
            radMaskedEditBox1.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals;
     
            Binding binding = new Binding("Value", data, "Value", true);
            binding.Parse += Binding_Parse;
           
            radMaskedEditBox1.DataBindings.Add(binding);
        }
     
        private void Binding_Parse(object sender, ConvertEventArgs e)
        {
            if (e.Value == "" && e.DesiredType == typeof(int?))
            {
                e.Value = null;
            }
        }
     
        private void radButton1_Click(object sender, EventArgs e)
        {
            data.Value = null;
            
        }
     
        private void radButton2_Click(object sender, EventArgs e)
        {
            Console.WriteLine(data.Value);
        }
    }
    class MyData :  INotifyPropertyChanged
    {
        int? nullableValue = null;
     
        public int? Value
        {
            get
            {
                return nullableValue;
            }
            set
            {
                nullableValue = value;
                OnPropertyChanged("Value");
            }
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

    I hope this will be useful. 

    Regards,
    Dimitar
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Michael
    Michael avatar
    41 posts
    Member since:
    Oct 2010

    Posted 04 Sep Link to this post

    Hi,

     

    It has been a while since I asked the question above, but thank you for your prompt reply.  I am developing another program where I need another control for currency, but I need to be binded to a nullable decimal property.  I've inherited from your RadMaskedEditBox control and was able to make it work, but I have 2 outstanding issues.

     

    1. I used your suggestion above to handle Parse event of Binding object to handle null values.  But is it possible to integrate this into my control so that I don't have to worry about handling this property each time I bind this control.

    2. When user selects the whole text and presses delete, I would like for the Value to be set to 0.  But it seems like $0.00 is always substituted there. 

    Please take a look at my code below and let me know what else I can do to handle 2 situations above.

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using Telerik.WinControls.Analytics;
    using Telerik.WinControls.UI;
     
    namespace AllergyCanada.WinControls.UI
    {
        public class MidexCurrencyEditBox : RadMaskedEditBox
        {
            public MidexCurrencyEditBox() : base()
            {
                MaskType = Telerik.WinControls.UI.MaskType.Numeric;
                Mask = "C2";
                TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
                MidexCurrencyEditBox radMaskedEditBox = this;
                base.ValueChanged += new EventHandler(radMaskedEditBox.OnCurrencyValueChanged);
                MidexCurrencyEditBox radMaskedEditBox1 = this;
                base.ValueChanging += new CancelEventHandler(radMaskedEditBox1.OnCurrencyValueChanging);
            }      
     
     
            protected override void Dispose(bool disposing)
            {
                MidexCurrencyEditBox radMaskedEditBox = this;
                base.ValueChanged -= new EventHandler(radMaskedEditBox.OnCurrencyValueChanged);
                MidexCurrencyEditBox radMaskedEditBox1 = this;
                base.ValueChanging -= new CancelEventHandler(radMaskedEditBox1.OnCurrencyValueChanging);
                base.Dispose(disposing);
            }
     
     
            [Bindable(true)]
            [Browsable(true)]
            [Category("Behavior")]
            [DefaultValue("")]
            [Description("Gets or sets the value associated to the mask edit box")]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
            public decimal? CurrencyValue
            {
                get
                {
                    if (base.MaskedEditBoxElement.Value == null)
                        return null;
     
                    return decimal.Parse(base.MaskedEditBoxElement.Value.ToString(), NumberStyles.Currency);
                }
                set
                {
                    base.MaskedEditBoxElement.Value = value;
                    OnNotifyPropertyChanged("CurrencyValue");
                }
            }
     
            /// <summary>
            /// Occurs when the editing value has been changed
            /// </summary>
            [Category("Action")]
            [Description("Occurs when the editing currency value has been changed")]
            public event EventHandler CurrencyValueChanged;
     
     
            /// <summary>
            /// Occurs when the editing value is changing.
            /// </summary>
            [Category("Action")]
            [Description(" Occurs when the editing currency value is changing.")]
            public event CancelEventHandler CurrencyValueChanging;
     
     
            protected virtual void OnCurrencyValueChanged(object sender, EventArgs e)
            {
                this.CurrencyValueChanged?.Invoke(this, e);
                this.OnNotifyPropertyChanged("CurrencyValue");
                ControlTraceMonitor.TrackAtomicFeature(this, "CurrencyValueChanged", this.Text);
            }
     
            /// <summary>
            /// Fires the ValueChanging event
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected virtual void OnCurrencyValueChanging(object sender, CancelEventArgs e)
            {
                this.CurrencyValueChanging?.Invoke(this, e);
            }
     
        }
    }
  5. Dimitar
    Admin
    Dimitar avatar
    1404 posts

    Posted 06 Sep Link to this post

    Hello Michael,

    Thank you for writing back.

    1. Yes this is possible, you will need to use the DataBindings CollectioChanged event to determine when a binding is added:
    public MidexCurrencyEditBox() : base()
    {
       //other code omitted
      
        DataBindings.CollectionChanged += DataBindings_CollectionChanged;
    }
      
    private void DataBindings_CollectionChanged(object sender, CollectionChangeEventArgs e)
    {
        if (e.Action == CollectionChangeAction.Add && e.Element is Binding)
        {
            var binding = e.Element as Binding;
            binding.Parse += Binding_Parse;
        }
    }

    2. Please note that the format in the masked edit box depends on the mask and it cannot be changed for particular values only. 

    I hope this will be useful. Let me know if you have additional questions.

    Regards,
    Dimitar
    Telerik by Progress
    Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
Back to Top