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.
3 Answers, 1 is accepted
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
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); } }}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
