Динамическая генерация ActiveX на форме
От: DAA Россия  
Дата: 09.07.03 12:34
Оценка:
Задача: динамически создать ActiveX контрол на форме при загрузке (VB.Net)

Беру свой старый добрый ActiveX контрол, цепляю к оболочке. Оболочка честно генерит для контрола враппер через AxHost. На событии Form_Load присваиваю переменной новую инстанцию контрола и добавляю переменную в коллекцию Form.Contols.

Если ничего дальше не делать (работая только с наследными от AxHost пропертями — размер, положение), то контрол нормально появляется на форме. Но нафиг мне он пустой нужен? Правильно, пытаюсь вызвать свойства или методы (не наследные) этого контрола. На любой вызов получаю исключение AxHost.InvalidActiveXStateException, т.е. якобы объект находится в непонятном состоянии. Если необходимые мне вызовы повесить на кнопку (т.е. вызвать после отработки/возврата из Form_Load), то контрол совершенно чудно работает.

Способа "активировать" или перевести в другое "состояние" созданный элемент я не нашел. Попытки вызывать метод AxHost.CreateControl (который якобы принудительно создает контрол) тоже результата не дают.

Что тут можно еще придумать?




23.12.03 18:12: Перенесено модератором из '.NET' — AVK
Re: Динамическая генерация ActiveX на форме
От: Аноним  
Дата: 09.07.03 13:01
Оценка:
Здравствуйте, DAA, Вы писали:

DAA>Способа "активировать" или перевести в другое "состояние" созданный элемент я не нашел. Попытки вызывать метод AxHost.CreateControl (который якобы принудительно создает контрол) тоже результата не дают.


попробуй по reflection вызвать protected метод AttachInterfaces. Это изменит состояние Ax.
Re: Динамическая генерация ActiveX на форме
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 09.07.03 13:01
Оценка:
Здравствуйте, DAA, Вы писали:

DAA>Что тут можно еще придумать?


Вобще то дизайнер должен был вставить в код инициализации что то вроде этого:

this.axWebBrowser1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axWebBrowser1.OcxState")));
... << RSDN@Home 1.1 beta 1 >>
AVK Blog
Re[2]: Динамическая генерация ActiveX на форме
От: DAA Россия  
Дата: 11.07.03 07:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Вобще то дизайнер должен был вставить в код инициализации что то вроде этого:


AVK>this.axWebBrowser1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axWebBrowser1.OcxState")));




Да, дизайнер вставлет этот код, если я помещаю контрол на форму в дизайнере:

Me.ctl.OcxState = CType(resources.GetObject("ctl.OcxState"), System.Windows.Forms.AxHost.State)

Но я-то хочу его добавлять динамически.
Документация по AxHost и обертыванию контролов оставляет, мягко говоря, желать лучшего.
Re: Проблема решена наполовину
От: DAA Россия  
Дата: 11.07.03 08:44
Оценка:
Позор мне! Не догадался помотреть, что за код инициализации вставляет система для контролов, сгенеренных вручную.
Итого, для динамической генерации ActiveX контрола нужно:

Определить объектную переменную
Friend WithEvents ctl As AxCtl.AxCtl

Создать экземпляр
ctl = New AxCtl.AxCtl

Добавить экземпляр контрола в коллекцию
Me.Controls.Add(ctl)

До вызова любого ненаследемого от AxHost метода выполнить следующий код:

CType(Me.ctl, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.ctl, System.ComponentModel.ISupportInitialize).EndInit()

Видимо, этот код выполняет переопределенные AxHost-ом методы какой-то инициализации.

После этого кода виполнение методов происходит без ошибок.

НО! Далее возникает другая проблема: вызов методов контрола НЕ ПРИВОДИТ К ЕГО ПЕРЕРИСОВКЕ.
Будем бороться...
Re[2]: Динамическая генерация ActiveX на форме
От: DAA Россия  
Дата: 11.07.03 09:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>попробуй по reflection вызвать protected метод AttachInterfaces. Это изменит состояние Ax.


Расскажи пжл, как это можно сделать?
Re[2]: Проблема решена наполовину
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.07.03 18:17
Оценка:
Здравствуйте, DAA, Вы писали:

DAA>CType(Me.ctl, System.ComponentModel.ISupportInitialize).BeginInit()

DAA>CType(Me.ctl, System.ComponentModel.ISupportInitialize).EndInit()

DAA>Видимо, этот код выполняет переопределенные AxHost-ом методы какой-то инициализации.


Этот код скорее всего выполняет вызов IPersistXxx::InitNew инициализирующий контрол и делает контрол UI-активным.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Проблема решена наполовину
От: kly Россия  
Дата: 21.01.04 02:02
Оценка:
Здравствуйте, VladD2, Вы писали:

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


DAA>>CType(Me.ctl, System.ComponentModel.ISupportInitialize).BeginInit()

DAA>>CType(Me.ctl, System.ComponentModel.ISupportInitialize).EndInit()

DAA>>Видимо, этот код выполняет переопределенные AxHost-ом методы какой-то инициализации.


VD>Этот код скорее всего выполняет вызов IPersistXxx::InitNew инициализирующий контрол и делает контрол UI-активным.


Ввиду того, что никто не опубликовал ответ на заданный вопрос полностью то приведу собственное решение проблемы (честно слямзенное у MS). Может кому сэкономит полчаса


public void InitAX()
{
    // необходимо создать ActiveX FlexGrid7
    // Создаем wrapper при помощи AxImp.exe, далее..
    // ФУНКЦИЯ ИНИЦИАЛИЗАЦИИ...
    DocumentGrid = new AxVSFlex7.AxVSFlexGrid();
    // несмотря на то, что wrapper создан сам ActiveX еще не создан.
    // работать с методами ActiveX'а можно будет после создания - перехватываем событие создания
    DocumentGrid.HandleCreated += new EventHandler(DocumentGrid_HandleCreated);
    DocumentGrid.BeginInit();
    DocumentGrid.Anchor = AnchorStyles.Top | AnchorStyles.Left;            
    DocumentGrid.Dock = DockStyle.Fill;
    this.Controls.Add( DocumentGrid );                    
    DocumentGrid.EndInit();
}

private void DocumentGrid_HandleCreated(object sender, EventArgs e)
{
    // после перехвата этого события можно работать не опасаясь выброса
    // исключения о неправильном состоянии ActiveX
    DocumentGrid.OutlineBar = VSFlex7.OutlineBarSettings.flexOutlineBarSimple;
    DocumentGrid.Cols = 11;
    DocumentGrid.Rows = 40;
    //....
}
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, — недооценка изобретательности клинических идиотов.

http://www.inconteam.com
Re[4]: Проблема решена наполовину
От: Аноним  
Дата: 25.05.06 20:37
Оценка:
Здравствуйте, kly, Вы писали:

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


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


DAA>>>CType(Me.ctl, System.ComponentModel.ISupportInitialize).BeginInit()

DAA>>>CType(Me.ctl, System.ComponentModel.ISupportInitialize).EndInit()

DAA>>>Видимо, этот код выполняет переопределенные AxHost-ом методы какой-то инициализации.


VD>>Этот код скорее всего выполняет вызов IPersistXxx::InitNew инициализирующий контрол и делает контрол UI-активным.


kly>Ввиду того, что никто не опубликовал ответ на заданный вопрос полностью то приведу собственное решение проблемы (честно слямзенное у MS). Может кому сэкономит полчаса



kly>
kly>public void InitAX()
kly>{
kly>    // необходимо создать ActiveX FlexGrid7
kly>    // Создаем wrapper при помощи AxImp.exe, далее..
kly>    // ФУНКЦИЯ ИНИЦИАЛИЗАЦИИ...
kly>    DocumentGrid = new AxVSFlex7.AxVSFlexGrid();
kly>    // несмотря на то, что wrapper создан сам ActiveX еще не создан.
kly>    // работать с методами ActiveX'а можно будет после создания - перехватываем событие создания
kly>    DocumentGrid.HandleCreated += new EventHandler(DocumentGrid_HandleCreated);
kly>    DocumentGrid.BeginInit();
kly>    DocumentGrid.Anchor = AnchorStyles.Top | AnchorStyles.Left;            
kly>    DocumentGrid.Dock = DockStyle.Fill;
kly>    this.Controls.Add( DocumentGrid );                    
kly>    DocumentGrid.EndInit();
kly>}

kly>private void DocumentGrid_HandleCreated(object sender, EventArgs e)
kly>{
kly>    // после перехвата этого события можно работать не опасаясь выброса
kly>    // исключения о неправильном состоянии ActiveX
kly>    DocumentGrid.OutlineBar = VSFlex7.OutlineBarSettings.flexOutlineBarSimple;
kly>    DocumentGrid.Cols = 11;
kly>    DocumentGrid.Rows = 40;
kly>    //....
kly>}




kly>

Выручил, спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.