Тут эта тема поднималась несколько раз, но солюшена для моего случая я не нашёл.
Простейший случай: int <-> string, со списком стандартных значений.
Всё работает, список работает, конвертится. НО есть ОДНА проблема: при _двойном клике_ на поле, должно выбираться следующее значение из списка, но у меня вылетает ошибка грида: Invalid property value->Cannot widen from target type to primitive type.
Если _MyField организовать как string, то двойной клик работает правильно, но желательно int, и не вводить дополнительных свойств.
Вторые сутки... гугл, мсдн, рсдн...
public class MyClass
{
private int _MyField;
[TypeConverter(typeof(MyFieldConverter))]
public int MyField
{
get
{
return _MyField;
}
set
{
_MyField = value;
}
}
}
public class MyFieldConverter: TypeConverter
{
private ArrayList _values = null;
public MyFieldConverter()
{
_values = new ArrayList(new string[] { "Value 1", "Value 2", "Value 3" });
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(_values);
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if(sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if(value is string)
return _values.IndexOf((string)value);
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if(destinationType == typeof(int))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if(destinationType == typeof(System.String) && value is int)
return _values[(int)value].ToString();
return base.ConvertTo(context, culture, value, destinationType);
}
}
Проблема вот в чем:
При двойном клике PropertyGrid запрашивает поддерживается ли список значений
GetStandardValuesSupported и если,
то он получает этот список
GetStandardValues. У каждолго
GridEntry хронится индекс выброного значения,
этот индекс изменяем и св-ву присывае значение
GetStandardValues[новыйИндекс], а так как
string к
int не приводится, то мы получаем вот такой вот прикол.
Вывод:
А вообще-то это твая имплементация GetStandardValues ошибочная.
MSDN : Returns a collection of standard values for the data type this type converter is designed for.
public void DoubleClickRow(int row, bool toggleExpand, int type)
{
GridEntry entry = this.GetGridEntryFromRow(row);
... //здесь нет ничего интересного
// получить индекс текущего элемента
int index = this.GetCurrentValueIndex(entry);
if (index != -1) // элемент выбран
{
// получить список доступных объектов
// обратите внимание от куда получаем список
object[] array = entry.GetPropertyValueList();
// установить новый индекс
if (index >= (array.Length - 1))
index = 0;
else
index += 1;
// а теперь внимание !!! и что мы пытаемся присвоить ???
CommitValue(array[index]);// в конечном итоге приходим у вызову propertyInfo.SetValue(PropertyOwner, value);
// выбрать строку
SelectRow(this.selectedRow);
//выход из функции
return;
}
... //здесь нет ничего интересного
}
public virtual object[] GetPropertyValueList()
{
ICollection collection = this.TypeConverter.GetStandardValues(this);
if (collection != null)
{
object[] array = new object[collection.Count];
collection.CopyTo(array, 0);
return array;
}
return new object[0];
}
... << Rsdn@Home 1.1.4 beta 1 >>
Здравствуйте, V.Petrovski, Вы писали:
VP>Проблема вот в чем:

Спасибо! Супер! Перелопатил — заработало!
Anakrino рулит, только терпения не хватает