То, каким образом PropertyGrid преобразовывает строку, введённую пользователем, к типу вашего свойства, определяется специальным объектом-наследником класса TypeConverter.
Вы можете переопределить TypeConverter для вашего конкретного свойства с помощью атрибута TypeConverterAttribute. Для этого нужно создать класс-наследник TypeConverter. По умолчанию, для свойств типа Int32 используется класс Int32Converter (который является наследником TypeConverter). Поскольку нас в целом устраивает его рабора и нужно поменять всего лишь небольшую деталь, унаследуем наш класс от него.
После этого нужно перекрыть метод ConvertFrom (а если вы хотите преобразовывать ещё из каких-то типов, то и CanConvertFrom) и реализовать в нём преобразование из строк так, чтобы окошка с ошибкой не возникало.
Вот моя реализация:
/// <summary>
/// Конвертер для типа Int32, не выбрасывающий окошко с ошибкой
/// </summary>public class MyIntConverter : Int32Converter
{
/// <summary>
/// Overrides <see cref="TypeConverter.ConvertFrom"/>
/// </summary>public override object ConvertFrom(
ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
object value )
{
if ( value is string )
{
// Если нас просят сконвертировать из строки, займёмся этим деломstring str = value as string;
if ( Regex.IsMatch( str, @"\d+" ) )
{
return int.Parse( str );
}
else
{
// Если в строке пришло не число, вернём 85
// Ну так вот мне захотелось! :-)return 85;
}
}
else
{
// Если же наше значение - не строка, то просто передадим управление
// "стандартной" реализацииreturn base.ConvertFrom( context, culture, value );
}
}
}
Теперь нужно этот конвертер прицепить к нашему свойству:
[DefaultValue(0)]
[ TypeConverter( typeof( MyIntConveter ) ) ]
public int Count
{
get {return _Count;}
set
{
_Count = value;
}
}
private int _Count;
Попробуйте теперь поставить ваш объект в PropertyGrid и ввести какое-нибудь недопустимое значение. На его место сразу подставится 85, без всяких окошек.
Данная информация предоставляется на условиях «КАК ЕСТЬ», без предоставления каких-либо гарантий и прав. Используя данную информацию, вы соглашаетесь с тем, что (i) Майкрософт не несет ответственности за использование вами данной информации и (ii) вы принимаете на себя весь риск, связанный с использованием данной информации.
ИМХО, в этом и заключается сложность и муторность разработки элементов управления...
Используйте рефлексию + универсалный TypeConverter для упрощения...
> ИМХО, в этом и заключается сложность и муторность разработки элементов управления...
Используйте рефлексию + универсалный TypeConverter для упрощения...
А можно конкретнее ... вы предлагаете сделать адаптер/обертку вокруг TypeConverter уже имеющийся у свойства?
Да, идея вполне здравая. Стандартный TypeConverter для данного типа (в данном случае — Int32) можно получить с помощью метода TypeDescriptor.GetConverter. После этого ваш TypeConverter мог бы вызывать стандартный и ловить исключения, кидаемые "стандартным" converter'ом.
Однако, я нашёл другой способ.
PropertyGrid пользуется для показа сообщения об ошибке услугами сервиса IUIService. Поэтому, если вы реализуете этот интерфейс и сделаете его реализацию метода ShowMessage пустой, сообщения не будет.
Чтобы передать PropertyGrid'у ваш сервис, следует также реализовать интерфейс ISite и его метод GetService(), из которого возвращать ссылку на вашу реализацию IUIService. А ссылку на реализацию ISite следует присвоить свойству PropertyGrid.Site.
Если вам мало понятно, о чём речь выше (что вполне может быть), могу выслать пример.
Данная информация предоставляется на условиях «КАК ЕСТЬ», без предоставления каких-либо гарантий и прав. Используя данную информацию, вы соглашаетесь с тем, что (i) Майкрософт не несет ответственности за использование вами данной информации и (ii) вы принимаете на себя весь риск, связанный с использованием данной информации.
Данная информация предоставляется на условиях «КАК ЕСТЬ», без предоставления каких-либо гарантий и прав. Используя данную информацию, вы соглашаетесь с тем, что (i) Майкрософт не несет ответственности за использование вами данной информации и (ii) вы принимаете на себя весь риск, связанный с использованием данной информации.
прощу прощения.
пара месяцев уже прошла
а опубликовать этот пример есть возможность?
P.S.: сейчас как раз над этой проблеммой работаю
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re: PropertyGrid убивает наповал :(
От:
Аноним
Дата:
04.01.05 10:49
Оценка:
Опубликовал.
Файл с кодом и минимальным объяснением лежит здесь.
Здесь также можно посмотреть некоторые другие примеры из созданных мной, если вам интересно.
Данная информация предоставляется на условиях «КАК ЕСТЬ», без предоставления каких-либо гарантий и прав. Используя данную информацию, вы соглашаетесь с тем, что (i) Майкрософт не несет ответственности за использование вами данной информации и (ii) вы принимаете на себя весь риск, связанный с использованием данной информации.