Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Создание дизайнера


Автор: Andrew_D 25.7.2007, 23:00
Всем привет!

Столкнулся с проблемой создания собственного дизайнера для своего контрола  smile . Помогите, пожалуйста, примером. smile 

Пробовал с примера на VB перейти на C#, камнем предкновения стала строка:      CType(Me.Control, NewPanel).GradEditor()
Как я понял, GradEditor() - это метод (или свойство) создаваемого компонента.  smile  Как это написать на C# ???

Буду рад любой информации! Заранее спасибо!

Автор: mihryak 26.7.2007, 11:13
вот так показываю форму с диалогом
Код

            private class GroupsEditor : UITypeEditor
            {
                private IWindowsFormsEditorService editorService = null;

                public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
                {
                    editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                    if (editorService == null)
                    {
                        return value;
                    }

                    UserRights rights = context.Instance as UserRights;
                    if (rights == null)
                    {
                        throw new ArgumentException("Invalid context.");
                    }
                    int userId = rights.row.Id;
                    

                    GroupsForm groupEditor = new GroupsForm(ViewState.DisplayUsers, userId);
                    groupEditor.ShowDialog();
                    return null;
                }

                public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
                {
                    return UITypeEditorEditStyle.Modal;
                }
            }


а вот так выглядит само свойство
Код

            [Editor(typeof(Organizer.Rights.UserRights.GroupsEditor), typeof(UITypeEditor))]
            public string Groups
            {
                get { return null; }
            }

Автор: Andrew_D 26.7.2007, 12:15
Спасибо, сейчас попробую! 

...попробовал.

Если не сложно, расскажи, пожалуйста, по пунктам,  как мне создать рабочий проект с твоим примером

Автор: Naum 26.7.2007, 13:05
Цитата(Andrew_D @  26.7.2007,  00:00 Найти цитируемый пост)
CType(Me.Control, NewPanel).GradEditor()

На C# это будет выглядеть так
Код

((NewPanel)this.Control).GradEditor();

Автор: Andrew_D 26.7.2007, 13:26
Спасибо! С этим разобрался...

Возникла друга проблема:

Создал свой конторол MyButton: Button, добавил ему свойство "номер" (private int nomer), добавил метод для доступа к нему

public int Nomer 
        { 
            get { return nomer; } 
            set { nomer = value; }
        }

В этом же классе добавил функцию, которая будет вызываться из дизайнера

public void Number() 
        { 
            
            dialog_number form = new dialog_number();//  мое диалоговое окно для ввода номера
            
            base.Invalidate();// не знаю, взял из примера на VB
            form.Text = this.Nomer.ToString();
            this.Nomer = form.MyShow();// присвоение введеного номера, ф-ия MyShow возвращает введенное значение
            base.Invalidate();// не знаю, взял из примера на VB
            
        }

В дизайнере прописал вызов:  ((Button_D)this.Control).Number();

Суть проблемы: если добавить контрол на форму и сразу же присвоить номер, то номер присваивается (это смотрю в #region Windows Form Designer generated code). Но при следующих попытках изменить номер ничего не выходит!!!

Может быть надо как-то обновлять #region Windows Form Designer generated code?

Автор: mihryak 26.7.2007, 13:27
1. У тебя есть некий класс, одно из св-в которого ты хочешь дизайнить через PropertyGrid.
у меня это св-во
Код

            public string Groups
            {
                get { return null; }
            }

null возвращаю, чтобы ничего не писалось в гриде

2. Нужно создать форму-дизайнер для этого св-ва. Для передачи ей того, что собственно будет редактироваться, нужно завести у этой формы параметризированный конструктор.

3. Теперь создадим класс, отвечающий за вызов этой формы.
Код

            private class GroupsEditor : UITypeEditor
            {
                private IWindowsFormsEditorService editorService = null;

                public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
                {
                    ...
                }
                public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
                {
                    ...
                }
            }

переопределённый метод EditValue() занимается тем, что вызывает форму-дизайнер. При этом параметр ITypeDescriptorContext context содержит в себе свойство Instance, содержащее собственно экземпляр редактируемого класса (не свойство!).
Код

                public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
                {
                    editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                    if (editorService == null)
                    {
                        return value;
                    }
                    UserRights rights = context.Instance as UserRights;
                    if (rights == null)
                    {
                        throw new ArgumentException("Invalid context.");
                    }
                    int userId = rights.row.Id;
                    
                    GroupsForm groupEditor = new GroupsForm(ViewState.DisplayUsers, userId);
                    groupEditor.ShowDialog();
                    return null;
                }

ещё один переопределённый метод GetEditStyle() задаёт тип дизайнера. в нашем случае - модальная форма.
Код

                public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
                {
                    return UITypeEditorEditStyle.Modal;
                }


4. Теперь нужно указать нашему свойству, что оно имеет свой собственный дизайнер, это делается атрубутом Editor, где первый параметр - тип написанного "вызывальщика" формы-дизайнера.
Код

[Editor(typeof(Organizer.Rights.UserRights.GroupsEditor), typeof(UITypeEditor))]


При выборе этого свойства в PropertyGrid'е будет доступна стандартная кнопочка с троеточием, открывающаяя нашу форму-дизайнер.

Автор: Andrew_D 26.7.2007, 13:45
Вопрос по пункту 2.
 Как создать форму-дизайнер для свойства? Т.е. в мой компонент добавить NewItem...Windows Form?

Автор: mihryak 26.7.2007, 13:47
ну да, в проект с контролом добавить WinForm

Автор: Andrew_D 26.7.2007, 13:54
класс  private class GroupsEditor : UITypeEditor  добавлять в мой класс?

почему-то выдает много ошибок... И в reference вроде все подключил...

Автор: mihryak 26.7.2007, 16:45
у меня он определён в том же файле, что и сам класс с редактируемым свойством
в общем-то, это не правильно smile писал давно, сейчас бы поместил в отдельный файл
если будет в отдельном - то private, конечно, нужно заменить на internal или public (второе хуже)

Автор: AndrewD 26.7.2007, 21:33
Извини меня, пожалуйста, что я так туплю (я еще начинающий!), у меня снова проблема!

Вставил твой код в тот же файл, где мой класс :

internal   class GroupsEditor : UITypeEditor
{
.........
}

Происходит следующая ругань:

D:\Андрей\Проекты\Свой интерфейс\forum\Class1.cs(41): The type or namespace name 'UserRights' could not be found (are you missing a using directive or an assembly reference?)
D:\Андрей\Проекты\Свой интерфейс\forum\Class1.cs(42): The name 'rights' does not exist in the class or namespace 'forum.GroupsEditor'
D:\Андрей\Проекты\Свой интерфейс\forum\Class1.cs(46): The type or namespace name 'rights' could not be found (are you missing a using directive or an assembly reference?)
D:\Андрей\Проекты\Свой интерфейс\forum\Class1.cs(48): The type or namespace name 'GroupsForm' could not be found (are you missing a using directive or an assembly reference?)
D:\Андрей\Проекты\Свой интерфейс\forum\Class1.cs(49): The type or namespace name 'groupEditor' could not be found (are you missing a using directive or an assembly reference?)

Что такое UserRights и rights - вообще не понимаю!(такой уж я), а GroupsForm - это наверное public class GroupsForm: Form , т.е. форма-дизайнер ?

И еще вопрос, параметры для конструктора ViewState.DisplayUsers, userId - что за переменные? Что надо добавить на форму-дизайнер?
Может я что-то не подключил?
У меня:
using System;
using System.ComponentModel;
using System.Windows.Forms.Design;
using System.Drawing.Design;
 а в reference:
forum    (-   мой компонент)
System
System.Data
System.Drawing
System.Windows.Forms



Автор: mihryak 26.7.2007, 22:10
ой  smile 

Цитата(AndrewD @  26.7.2007,  21:33 Найти цитируемый пост)
The type or namespace name 'UserRights' could not be found

UserRights - это мой класс, свойство Groups которого и подлежит отображению в дизайнере. Заменить на свой.
Цитата(AndrewD @  26.7.2007,  21:33 Найти цитируемый пост)
The type or namespace name 'GroupsForm' could not be found

GroupsForm - это класс формы-дизайнера. Заменить на свой

rights и groupForm - просто локальные переменные, после правильно указанных классов всё встанет на свои места.

Цитата(AndrewD @  26.7.2007,  21:33 Найти цитируемый пост)
И еще вопрос, параметры для конструктора ViewState.DisplayUsers, userId - что за переменные? Что надо добавить на форму-дизайнер?

это параметры конструктора формы-дизайнера, у меня - GroupsForm. в большинстве случаев резонно будет передавать в этот конструктор context.Instance as MyClassWithDesignableProperty

Автор: AndrewD 26.7.2007, 22:21
Спасибо, попробую. Если что, то напишу smile 

Автор: mihryak 27.7.2007, 00:48
вот написал тестик

Автор: AndrewD 31.7.2007, 22:30
Спасибо большое mihryak !!! Вроде разобрался, но все равно присутствуют косяки smile  


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)