Completed
Last Updated: 01 Oct 2014 13:01 by ADMIN
ADMIN
George
Created on: 02 Jul 2014 12:01
Category: PropertyGrid
Type: Bug Report
0
FIX. RadPropertyGrid the ConvertFrom method of a TypeConverter is not called when the SelectedObject has a string property
To reproduce:

Set the following object as selected of RadPropertyGrid: 

class TestClass : System.ComponentModel.INotifyPropertyChanged
{
    private string loggingType = "0";

    [TypeConverter(typeof(CustomListConverter)), CategoryAttribute("Logging Settings")]
    public string LoggingType
    {
        get { return loggingType; }
        set
        {
            loggingType = value;
            OnPropertyChanged("LoggingType");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

And use the following converter:

public class CustomListConverter : System.ComponentModel.StringConverter
{
    ArrayList _AllStringValues = new ArrayList();
    Hashtable _Map = new Hashtable();

    public CustomListConverter()
    {
    }

    public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext conte
    {
        FillValuesFromContext();
        StandardValuesCollection standardValues = new StandardValuesCollection(_AllStringValues);
        return standardValues;
    }

    private void FillValuesFromContext()
    {
        if (_AllStringValues.Count > 0)
            return;

        _AllStringValues.Clear();
        _Map.Clear();

        string str = "-5,Fatal|-4,Error|-3,Warning|-2, Info|-1,Debug|0,Trace";

        string[] strMapVals = str.Split('|');
        for (int i = 0; i < strMapVals.Length; i++)
        {
            string[] strVals = strMapVals[i].Split(',');
            if (strVals.Length != 2)
                continue;

            _AllStringValues.Add(strVals[0].Trim());
            _Map.Add(strVals[0].Trim(), strVals[1].Trim());
        }
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        FillValuesFromContext();

        string displayString = "";

        IEnumerator enumTable = _Map.Keys.GetEnumerator();

        while (enumTable.MoveNext())
        {
            if (_Map[enumTable.Current] as string == value as string)
            {
                displayString = enumTable.Current as string;
                break;
            }
        }

        return displayString;
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        FillValuesFromContext();

        if (null != value && _Map.ContainsKey(value.ToString()))
        {
            return _Map[value];
        }

        return value;
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }
}

When you start the application you will see that the value of the property is set to -1, while it should be converted to 'Debug'

Workaround:

Create a custom PropertyGridItem:

public class MyPropertyGridItem : PropertyGridItem
{
    public MyPropertyGridItem(PropertyGridTableElement element)
        : base(element)
    {
    }

    public override string FormattedValue
    {
        get
        {
            string baseFormattedValue =  base.FormattedValue;
            TypeConverter converter = TypeConverter;

            if (converter != null && converter.CanConvertTo(this, typeof(string)))
            {
                baseFormattedValue = converter.ConvertToString(this, System.Threading.Thread.CurrentThread.CurrentCulture, this.Value);
            }

            return baseFormattedValue;
        }
        set
        {
            base.FormattedValue = value;
        }
    }
}

Use it by subscribing to the CreateItem event:

void radPropertyGrid1_CreateItem(object sender, Telerik.WinControls.UI.CreatePropertyGridItemEventArgs e)
{
    e.Item = new MyPropertyGridItem(this.radPropertyGrid1.PropertyGridElement.PropertyTableElement);
}

0 comments