Overview:-
We are using RadMaskedNumericInput control embedded in a RadGridView Cell for allowing user to edit the existing decimal values. Also, the Foreground property of the RadMaskedNumericInput control is bound to a decimal value and a converter (named ValueToColorConvertor) is applied which turns the foreground red for negative numbers and keep it black for non-negative number.
Problem:-
Now the problem that on refreshing the data source of the GridView (in whoes cell RadMaskedNumericInput control is embedded) RadMask control's foreground behave's awkwardly and for few of the cells sometime a positive number is shown red and sometimes a negative number is shown black (see the attached snapshot)
Analysis:-
I have verified that when data is refreshed for parent RadGridView then ValueToColor foreground converter is not invoked for all the radmaskednumericInput control instances. this converter is invoked randomly for 7-8 instances out of 13 instances shown in the controls attached snapshot.
Converter and Behavior applie are :-
1) ValueToColorConverter:- converts decimal value to Red/Black colour brush during first time load/refresh of the data.
2) TargetExposureConverter:- which is a multivalue converter to attach parameters to the RadMaskedNumericInput valuechanging command
3) RadMaskedInputValueChangingBehavior:- This behaviour changes the foreground of the RadMaskedNumericInput control's text on value changed.
public class ValueToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var brush = new SolidColorBrush(Colors.Black);
Double doubleValue = 0.0;
Double.TryParse(value.ToString(), out doubleValue);
if (doubleValue < 0)
brush =
new SolidColorBrush(Colors.Red);
return brush;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
-----------------------------------------------
public class TargetExposureConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return null;
if (values.Length != 2)
throw new ApplicationException("Expecting 2 parameters in TargetExposureConverter");
var targetExposureCmdParameter = new TargetExposureEditedCmdParam();
decimal value;
decimal.TryParse(System.Convert.ToString(values[0]), out value);
targetExposureCmdParameter.TargetExposure = value;
var targetExposureCell = values[1] as GridViewCell;
if (targetExposureCell != null && targetExposureCell.ParentRow != null)
{
targetExposureCmdParameter.CurrentRow = targetExposureCell.ParentRow.Item
as CcyExposureCurrencySummary;
}
return targetExposureCmdParameter;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
-----------------------------------
public class RadMaskedInputValueChangingBehavior : Behavior<RadMaskedInputBase>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.ValueChanging += OnValueChanging;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.ValueChanging -= OnValueChanging;
}
void OnValueChanging(object sender, RadMaskedInputValueChangingEventArgs e)
{
var maskedInputControl = sender as RadMaskedNumericInput;
if (maskedInputControl == null)
return;
if (e.NewValue == null)
return;
double newVal;
if (!double.TryParse(Convert.ToString(e.NewValue), out newVal))
return;
maskedInputControl.Foreground = newVal < 0
?
Brushes.Red
:
Brushes.Black;
}
}