PropertyGrid FAQ
От: Алексей Кирюшкин Россия http://malgarr.blogspot.com/
Дата: 07.12.06 09:45
Оценка: 2272 (58) +4
Статья:
PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



Авторы:
Алексей Кирюшкин

Аннотация:
Как заменить имя переменной в левой колонке “человеческим” именем свойства?
Как отобразить расширенную подсказку по свойству в нижнем окне?
Как сгруппировать свойства по категориям?
Как отобразить свойство, недоступное для редактирования?
Как заменить стандартные True/False в отображении свойств типа bool?
Как заменить стандартное отображение имен членов перечисления?
Как показать свою картинку для каждого значения из перечисления?
Как организовать выбор значения из выпадающего списка, формируемого программно?
Как реализовать отображение составного свойства?
Как организовать выбор файла с заданным расширением?
Как организовать редактирование свойства в собственной форме?
Как организовать редактирование свойства в выпадающем списке?
Как управлять видимостью свойства в зависимости от значения другого свойства?
Как избавиться от стандартного “(Collection)” в правой колонке для свойств-коллекций?
Как заменить стандартные подписи (Members, properties) в окне Collection Editor?
Как добавить в Collection Editor окно с расширенной подсказкой по редактируемым свойствам?
Как задать отличный от алфавитного порядок следования свойств внутри категории?
Как запомнить и восстановить положение разделителя колонок в PropertyGrid?
propertygrid
Re: PropertyGrid FAQ
От: S.Bludov Украина  
Дата: 16.01.07 16:33
Оценка: 3 (1) +1
Здравствуйте, Алексей Кирюшкин, Вы писали:

АК>Статья:

АК>PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



Спасибо за статью.
Как реализовать локализацию свойств в гриде?

Спасибо.
Re[2]: PropertyGrid FAQ
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 17.01.07 04:42
Оценка:
Здравствуйте, S.Bludov, Вы писали:

SB>Как реализовать локализацию свойств в гриде?


этим я еще не заморачивался
... << RSDN@Home 1.2.0 alpha rev. 668>>
Re[2]: PropertyGrid FAQ
От: D.Triton Украина  
Дата: 17.01.07 09:23
Оценка:
Здравствуйте, S.Bludov, Вы писали:

SB>Здравствуйте, Алексей Кирюшкин, Вы писали:


АК>>Статья:

АК>>PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



SB>Спасибо за статью.

SB>Как реализовать локализацию свойств в гриде?

SB>Спасибо.


Пример:


[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class DisplayNameLocalizedAttribute : DisplayNameAttribute
    {
        private Type resourceSource;
        private string resourceName;

        protected DisplayNameLocalizedAttribute()
        {
        }

        public DisplayNameLocalizedAttribute(Type resourceSource, string resourceName)
        {
            this.resourceSource = resourceSource;
            this.resourceName = resourceName;
            UpdateDisplayName();
        }

        public void UpdateDisplayName()
        {
            ResourceManager rm = new ResourceManager(resourceSource);
            DisplayNameValue = rm.GetString(resourceName);
        }
    }


Используем так:

public class YearRequestByMonthConfig : BaseReportConfig
    {
        //YearRequestByMonthRptConfigResources - компонент с ресурсами
        [DisplayNameLocalized(typeof (YearRequestByMonthRptConfigResources), "Department")]
        public string Department
        {
            get { return department; }
            set { department = value; }
        }
}
Re[3]: PropertyGrid FAQ
От: S.Bludov Украина  
Дата: 17.01.07 09:24
Оценка:
Здравствуйте, D.Triton, Вы писали:

Спасибо, Стас
Re: PropertyGrid FAQ
От: _FRED_ Черногория
Дата: 17.01.07 16:05
Оценка:
Здравствуйте, Алексей Кирюшкин, Вы писали:

АК>Статья:

АК>PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



Спасибо за статью

1. Имхо, часто, к сожелению, забывают в TypeCoverter-ах проверять "destType":
class BooleanTypeConverter : BooleanConverter
{
  public override object ConvertTo(ITypeDescriptorContext context, 
    CultureInfo culture,
    object value, 
    Type destType)
  {
    return (bool)value ? 
      "Есть" : "Нет";
  }

  public override object ConvertFrom(ITypeDescriptorContext context, 
    CultureInfo culture,
    object value)
  {
    return (string)value == "Есть";
  }
}


2.

Реализовать EnumTypeConverter, осуществляющий преобразование к строке с учетом атрибута Description…

ИМХО, DiaplayName гораздо умеснее в подобной ситуации. А не сделал ли кто уже подобный класс, но который умеет работать с Flags-enum-ами? То есть где было бы реализовано ConvertFrom из локализованной строки в значение? Всегда ли правильно будет использовать Thread.CurrentThread.CurrentUICulture для выбора вариантов или культуру можено как-то выцепить из контекста?

3.
 public override void PaintValue(PaintValueEventArgs e)
  {
    // картинки хранятся в ресурсах с именами, соответствующими
    // именам каждого члена перечисления Sex
    string resourcename = ((Sex)e.Value).ToString();

    // достаем картинку из ресурсов
    Bitmap sexImage =
      (Bitmap)Resources.ResourceManager.GetObject(resourcename);
    Rectangle destRect = e.Bounds;
    sexImage.MakeTransparent();

    // и отрисовываем
    e.Graphics.DrawImage(sexImage, destRect);
  }

Не надо ли вызывать sexImage.Dispose()?

4.

Как реализовать отображение составного свойства?


При использовании этого аттрибута с написанными мною UserControl-ами, на вкладке событий PropertyGrid-а почему-то не добавляются обработчики для компонентов, показанных через "ExpandableObjectConverter" Как с этим можно справиться?
Help will always be given at Hogwarts to those who ask for it.
Re[2]: PropertyGrid FAQ
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 17.01.07 16:17
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>2.

Реализовать EnumTypeConverter, осуществляющий преобразование к строке с учетом атрибута Description…

_FR>ИМХО, DiaplayName гораздо умеснее в подобной ситуации.

слово-то покрасивше, только компилятор говорит:

error CS0592: Attribute 'DisplayName' is not valid on this declaration type. It is valid on 'class, method, property, indexer, event' declarations only.


как это разрулить?
... << RSDN@Home 1.2.0 alpha rev. 669>>
Re[3]: PropertyGrid FAQ
От: _FRED_ Черногория
Дата: 17.01.07 16:55
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

_FR>>2.

Реализовать EnumTypeConverter, осуществляющий преобразование к строке с учетом атрибута Description…

_FR>>ИМХО, DiaplayName гораздо умеснее в подобной ситуации.

OE>слово-то покрасивше, только компилятор говорит:

OE>error CS0592: Attribute 'DisplayName' is not valid on this declaration type. It is valid on 'class, method, property, indexer, event' declarations only.

OE>как это разрулить?

Дать мне по башке, иначе никак Виноват, поторопился.

В любом случае, значение надо грузить из ресурсов, поэтому:
  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Field)]
  public class LocalisedDisplayNameAttribute : DisplayNameAttribute
  {
    #region Constructors\Destructor

    public LocalisedDisplayNameAttribute(string resourceName) : base(LoadResource(resourceName)) {

    }

    #endregion Constructors\Destructor

    #region Methods

    private static string LoadResource(string resourceName) {
      return Properties.Resources.ResourceManager.GetString(resourceName);
    }

    #endregion Methods
  }

  public enum MyValues
  {
    [LocalisedDisplayName(Resources.Value1)]
    Value1,

    [LocalisedDisplayName(Resources.Value2)]
    Value2,
  }
Help will always be given at Hogwarts to those who ask for it.
Re: PropertyGrid FAQ
От: Трубаров Вячеслав Украина  
Дата: 18.01.07 00:38
Оценка:
Здравствуйте, Алексей Кирюшкин, Вы писали:

АК>Статья:

АК>PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



Отличная статья.

Только вот такой вроде как простой вопрос возник (создание редакторов проблем не вызвало, а тут такая мелочь...):
PropertyGrid события не показывает, но ведь они есть в стандартном Properties окне дизайнера, который тоже отображает изменения сделанные атрибутами.
Это я к тому что такой атрибут как Category — не работает для event'ов. Это событие просто не появляется в Properties, хоть указывай атрибут, хоть не указывай. Никак нельзя сделать чтобы он показывался?


// для свойства, естесственно, работает

[Category("Category1")]
public int Position
{
  get { return position; }
  set { position = value; }
}

// а вот для события нет...

public delegate void ChangedEventHandler();

[Category("Category2")]
public ChangedEventHandler PositionChanged;


PositionChanged не появляется в Properties... Хотя он конечно доступен программно. Просто хотелось бы чтобы он был виден и через дизайнер.
Re[2]: PropertyGrid FAQ
От: _FRED_ Черногория
Дата: 18.01.07 07:27
Оценка: 10 (2)
Здравствуйте, Трубаров Вячеслав, Вы писали:

ТВ>Это я к тому что такой атрибут как Category — не работает для event'ов.


Работает.

ТВ>// а вот для события нет...
ТВ>public delegate void ChangedEventHandler();

ТВ>[Category("Category2")]
ТВ>public event ChangedEventHandler PositionChanged;


Без ключегвого свова "event": PositionChanged — лишь открытое поле.
... << RSDN@Home 1.2.0 alpha rev. 670>>
Now playing: «Тихо в лесу…»
Help will always be given at Hogwarts to those who ask for it.
Re: PropertyGrid и обновления свойств?
От: laad  
Дата: 18.01.07 10:50
Оценка:
кто-нибудь сталкивался с необходимостью отображения изменений (произошедших вне PropertyGrid) в гриде?
PropertyGrid, как я понял, даже не думает подписываться на изменения показываемых PropertyDescriptor — в студии, видимо,
он отслеживает события IComponentChangeService — если это так, как его туда подцепить?
Re[3]: PropertyGrid FAQ
От: Трубаров Вячеслав Украина  
Дата: 18.01.07 18:41
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Без ключегвого свова "event": PositionChanged — лишь открытое поле.


Тьфу ты, дырявая моя башка Точно, спасибо.
Re: PropertyGrid FAQ
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 19.01.07 08:08
Оценка:
АК>Статья:
PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



добавил до кучи "Как скрыть пароль при редактировании?"
... << RSDN@Home 1.2.0 alpha rev. 668>>
Re: PropertyGrid FAQ
От: acronim  
Дата: 06.02.07 09:06
Оценка:
Здравствуйте, Алексей Кирюшкин, Вы писали:

Может и оффтоп, но все же

На 1.2 в Гриде была официальная бага(не могу найти ссылку ) Проявление примерно следующее

Редакторуем класс, свойство которого массив обьектов(наример два). Обьекты имеют поля. Так вот если
1) розвернуть все плюсики, в т.ч. свойст обьектов в массиве, установить фокус на свойство обьекта в массиве (не уверен)
2) вызвать редактор массива
3) поудалять, подобавлять полей
4) закрыть редактор

Возникает "index out of bounds".

Лечилось написанием своего редактора (возможно и можно подцепить стандартный) массивов и перед выходом из UITypeEditor.EditValue сворачиванием дерева




// Принудительно обнновляем грид если редактировалась динамическая структура

PropertyGrid* m_propertyGrid =  __try_cast<GlobalizedPropertyGrid::GlobalizedObject*>(context->get_Instance())->PropGrid;
GridItem* gi = m_propertyGrid->SelectedGridItem;
GridItem* parent = NULL;
while (gi != NULL)
{
    parent = gi;
    gi = gi->Parent;
}
if (parent != NULL)
{
    GridItemCollection* coll = parent->get_GridItems();
    for(int i = 0; i < coll->Count; i++)
    {
        GridItem* child    = coll->get_Item(i);
        if (child->GridItemType == GridItemType::Category)
        {
            GridItemCollection* coll2 = child->get_GridItems();
            for(int i = 0; i < coll2->Count; i++)
            {
               coll2->get_Item(i)->Expanded = false;
            }
        }
        else
            child->Expanded = false;
    }                                                                    
}
m_propertyGrid->Refresh();


Более полный фрагмент



        // Отображает визальный диалог для редактирования<br> 
        // коллекции соответствующего типа<br>
        // Связь между редактируемым свойством и типом <br>
        // коллекции устанавливается статически в ресурсы <br>
        // программы во время разработки
        public __gc class FieldListCollectionUITypeEditor : public System::Drawing::Design::UITypeEditor 
            {
            public:
            FieldListCollectionUITypeEditor() {}
                        
            System::Drawing::Design::UITypeEditorEditStyle GetEditStyle(System::ComponentModel::ITypeDescriptorContext* context) {
                return UITypeEditorEditStyle::Modal;
            }

            // Редактирует свойство
            Object* EditValue(System::ComponentModel::ITypeDescriptorContext* context, System::IServiceProvider* provider, Object* value) {
                String* ResoursePath = S"NIST.VALUE";
                // Return the value if the value is not of type FieldBase* __gc[].
                
                // Необходимо включить проверку на входные данные
                // if (value->GetType() != __typeof(System::String)&&( value->GetType() != __typeof(System::Int32)))
                //      return value;
                String* propertyName = S"";
                if (context->get_PropertyDescriptor()!=NULL)
                {
                    propertyName = context->get_PropertyDescriptor()->get_Name();                
                }                
                //
                System::Reflection::Assembly* ass = System::Reflection::Assembly::GetEntryAssembly();
                // Now use table name and display name id to access the resources.  
                ResourceManager* rm = new ResourceManager(ResoursePath,ass);
                // Get the string from the resources.         
                System::String* n = rm->GetString(String::Concat(propertyName,S"TYPE"));
                if (n!=NULL)
                {
                    NIST::CollectionEditor* editor = new NIST::CollectionEditor();
                    
                    // инициализируем редактор                    
                    if (n->Equals(S"String"))
                    {    
                        FieldCollectionString* fc = __try_cast<FieldCollectionString*>(value);
                        //Create temp copy of colrction
                        FieldCollection* temp = new FieldCollectionString();
                        for (int i = 0; i < fc->Count; i++)
                        {
                            __try_cast<FieldCollectionString*>(temp)->Add(fc->get_Item(i));
                        }
                        editor->setSource(temp,n);
                    }
                    else if (n->Equals(S"DateTime"))
                    {
                        FieldCollectionDateTime* fc = __try_cast<FieldCollectionDateTime*>(value);
                        //Create temp copy of colrction
                        FieldCollection* temp = new FieldCollectionDateTime();
                        for (int i = 0; i < fc->Count; i++)
                        {
                            __try_cast<FieldCollectionDateTime*>(temp)->Add(fc->get_Item(i));
                        }
                        editor->setSource(temp,n);
                    }
                    else
                    {                    
                        FieldCollection* fc = __try_cast<FieldCollection*>(value);
                        //Create temp copy of colrction
                        FieldCollection* temp;
                        if (n->Equals(S"FieldDAI"))
                        {
                            temp = new FieldCollectionDAI();
                        }
                        else if (n->Equals(S"FieldCNO"))
                        {
                            temp = new FieldCollectionCNO();
                        }
                        else if (n->Equals(S"FieldORN"))
                        {
                            temp = new FieldCollectionORN();
                        }
                        else if (n->Equals(S"FieldNAM"))
                        {
                            temp = new FieldCollectionNAM();
                        }
                        else if (n->Equals(S"FieldGSA"))
                        {
                            temp = new FieldCollectionGSA();
                        }
                        else if (n->Equals(S"FieldFPR"))
                        {
                            temp = new FieldCollectionFPR();
                        }
                        else 
                            return value;

                        for (int i = 0; i < fc->Count; i++)
                        {
                            temp->Add(fc->get_Item(i));
                        }
                        editor->setSource(temp,n);                    
                    }
                    
                    // получаем результат
                    if (editor->ShowDialog()==DialogResult::OK)
                    {        
                        if (n->Equals(S"String"))
                        {    
                            value = __try_cast<FieldCollectionString*>(editor->collection);                        
                        }
                        else if (n->Equals(S"DateTime"))
                        {
                            value = __try_cast<FieldCollectionDateTime*>(editor->collection);
                        }
                        else
                            value = editor->collection;
                    }
                }
                
                // Принудительно обнновляем грид если редактировалась динамическая структура
                

                //if (context->get_Instance()->GetType() == __typeof(GlobalizedPropertyGrid::GlobalizedObject))
                {
                    PropertyGrid* m_propertyGrid =  __try_cast<GlobalizedPropertyGrid::GlobalizedObject*>(context->get_Instance())->PropGrid;
                    GridItem* gi = m_propertyGrid->SelectedGridItem;
                    GridItem* parent = NULL;
                    while (gi != NULL)
                    {
                        parent = gi;
                        gi = gi->Parent;
                    }
                    if (parent != NULL)
                    {
                        GridItemCollection* coll = parent->get_GridItems();
                        for(int i = 0; i < coll->Count; i++)
                        {
                            GridItem* child    = coll->get_Item(i);
                            if (child->GridItemType == GridItemType::Category)
                            {
                                GridItemCollection* coll2 = child->get_GridItems();
                                for(int i = 0; i < coll2->Count; i++)
                                {
                                   coll2->get_Item(i)->Expanded = false;
                                }
                            }
                            else
                                child->Expanded = false;
                        }                                                                    
                    }
                    m_propertyGrid->Refresh(); 
                }
                
                return value;
            }

            
            // Draws a representation of the property's value.
            void PaintValue(System::Drawing::Design::PaintValueEventArgs* e) {
                }

            // Indicates whether the UITypeEditor supports painting a
            // representation of a property's value.
            bool GetPaintValueSupported(System::ComponentModel::ITypeDescriptorContext* context) {
                return false;
            }
            };
Все должно быть просто
Re[2]: PropertyGrid и обновления свойств?
От: vensub Украина  
Дата: 06.02.07 09:53
Оценка:
Здравствуйте, laad, Вы писали:

L>кто-нибудь сталкивался с необходимостью отображения изменений (произошедших вне PropertyGrid) в гриде?

L>PropertyGrid, как я понял, даже не думает подписываться на изменения показываемых PropertyDescriptor — в студии, видимо,
L>он отслеживает события IComponentChangeService — если это так, как его туда подцепить?

внутри UITypeEditor что-то вроде:

IComponentChangeService ccs = provider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
ccs.OnComponentChanged(..);
Re[3]: PropertyGrid и обновления свойств?
От: laad  
Дата: 06.02.07 10:59
Оценка:
Здравствуйте, vensub, Вы писали:

V>Здравствуйте, laad, Вы писали:


L>>кто-нибудь сталкивался с необходимостью отображения изменений (произошедших вне PropertyGrid) в гриде?

L>>PropertyGrid, как я понял, даже не думает подписываться на изменения показываемых PropertyDescriptor — в студии, видимо,
L>>он отслеживает события IComponentChangeService — если это так, как его туда подцепить?

V>внутри UITypeEditor что-то вроде:


V>
V>IComponentChangeService ccs = provider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
V>ccs.OnComponentChanged(..);
V>


Спасибо Ж)
на самом деле, там несколько тоньше: нужно установить PropertyGrid.Site такой, чтобы он отвечал на GetService( typeof( IDesignerHost) )
только в таком случае PropertyGrid начинает запрашивать другие сервисы, в том числе IComponentChangeService.

Вообще говоря, похоже на некоторую нестыковку у микрософта — с одной стороны, PropertyDescriptor поддерживает в принципе оповещения об изменении значения, с другой — PropertyGrid на него забивает и использует сервис. Похоже, в ходе разработки поняли, что нужны транзакции для нормальной скорости работы всех связки — и сделали IComponentChangeService.
Re: PropertyGrid FAQ
От: Аноним  
Дата: 06.02.07 16:52
Оценка:
Здравствуйте, Алексей Кирюшкин, Вы писали:

АК>Статья:

АК>PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



Спасибо за статью.

Есть вопрос по editor-ам.
Есть тип MyCollectionEditor, производный от CollectionEditor.

Конструктор CollectionEditor выглядит так:

public CollectionEditor (Type collection_type)


Мне же нужно, чтобы конструктор моего класса MyCollectionEditor, принимал
помимо типа коллекции, ещё некоторые другие параметры, т.е. чтобы мой конструктор
выглядел вот так:

public MyCollectionEditor (Type collection_type, SomeType additional_data)


Так вот, возможно ли как-то прикрутить мой MyCollectionEditor к редактированию коллекции
в PropertyGrid?
Re: PropertyGrid FAQ
От: D.Triton Украина  
Дата: 06.02.07 19:29
Оценка:
Здравствуйте, Алексей Кирюшкин, Вы писали:

АК>Статья:

АК>PropertyGrid FAQ
Автор(ы): Алексей Кирюшкин
Дата: 06.12.2006
В данном FAQ собраны ответы на некоторые вопросы, возникающие при первом применении PropertyGrid.



АК>Авторы:

АК> Алексей Кирюшкин


Отличная статья, огромное спасибо.
Но у меня есть одна проблема.


Мне нужно сделать редактирование поля из БД.


пусть я должен хранить идентификатор сущности в БД, а показывать значение соотв. поля этому идентификатору.

К примеру, я храню идентификатор сущьности "Еденица измерения", а в поле PropertyGrid вместо цифрового идентификатора показывается его наименование.


У меня получилось это отчасти.

Показать имя по идентификатору.
Но как только мне понадобилось
вызывать соотв. форму выбора еденицы измерения (поле PropertyGrid редактируется только через соотв. модальное окно выбора ед. измерения) у меня ничего не получилось.


Прошу прощения за каламбур.


Итак есть класс Unit


public class Unit
{
private decimal unitId;


public decimal UnitId
{
   get{return unitId;}
   set{unitId = value;}
}
}



после того как я подсуну этот класс в PropertyGrid.SelectedObject, я хочу видеть в
отображаемом поле не Id, а наименование идентификатора.

Выбор Unit у меня происходит из отдельной формы. Ее вызов я делаю реализацией своего EditAttribute.

Но для преобразования Id в наименование я использовал потомка от DecimalConverter. Но ничего не получилось, когда я стал использовать и Editor и TypeConverter.
Результат — отображение только идентификатора.
Когда я комментил Editor, то все работало, но я не мог тогда использовать свою модальную форму для выбора единицы измерения.

Люди добрые помогите, или подскажите, что читать. У меня уже истерика начинается.

Большое всем спасибо
Re[2]: PropertyGrid FAQ
От: D.Triton Украина  
Дата: 07.02.07 10:22
Оценка:
Здравствуйте, D.Triton, Вы писали:


DT>Мне нужно сделать редактирование поля из БД.



DT>пусть я должен хранить идентификатор сущности в БД, а показывать значение соотв. поля этому идентификатору.



Решение очень простое.

Делается класс, который хранит как идентификатор, так и строковое представление (наименование сущности).


public class YearRequestByMonthConfig : BaseReportConfig
    {
        public class EntityHolder
        {
            public EntityHolder()
            {
            }

            public EntityHolder(decimal id, string name)
            {
                this.id = id;
                this.name = name;
            }

            public decimal Id
            {
                get { return id; }
                set { id = value; }
            }

            private decimal id;

            public string Name
            {
                get { return name; }
                set { name = value; }
            }
           
            public override string ToString()
            {
                return Name;
            }

            private string name;
        }


Далее при реализации выбора сущности из БД делаем чего-то такое:
internal class DepartmentSelectEditor : UITypeEditor
        {
            public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
            {
                return UITypeEditorEditStyle.Modal;
            }

            private object value;


            /// <summary>
            /// Реализация метода редактирования
            /// </summary>
            public override Object EditValue(
                ITypeDescriptorContext context,
                IServiceProvider provider,
                Object value)
            {
                this.value = value;
                if ((provider != null) &&
                    (((IWindowsFormsEditorService) provider.GetService(typeof (IWindowsFormsEditorService))) != null))
                {
                    IDepartmentExplorerPresenter dex = BLHelper.GetDepartmentExplorerPresenter();
                    dex.DepartmentSelect +=
                        delegate(object sender, DepartmentExplorerSelectionEventArgs args)
                            {
                                string name = DataProviderHelper.EnterpriseDAL.GetEnterpriseName(args.EnterpriseId);
                                this.value = new EntityHolder(args.EnterpriseId, name);
                            };

                    dex.ShowDepartmentExplorer();
                }
                value = this.value;
                this.value = null;
                return value;
            }
        }



А пол, которое редактируем (скажем какое-то подразделение)

отображаем так:

        [Browsable(true)]
        [DisplayNameLocalized(typeof (YearRequestByMonthRptConfigResources), "Department")]        
        [Editor(typeof (DepartmentSelectEditor), typeof (UITypeEditor))]        
            public EntityHolder Department
        {
            get { return department; }
            set { department = value; }
        }



Все работает просто супер

Всем спасибо.
Re: PropertyGrid FAQ
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 18.02.07 14:14
Оценка:
добавлено: "Как избавиться от ошибки “Конструктор для типа "System.String" не найден” при редактировании свойств типа StringCollection?"
... << RSDN@Home 1.2.0 alpha rev. 675>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.