Модераторы: gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическое создание сложных(составных) контролов 
:(
    Опции темы
SpaceSpace
Дата 28.4.2007, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 10.4.2007
Где: Самара

Репутация: 3
Всего: 10



Такая проблема.
Существует контрол "A". Сложный, т.е. В нем есть друге, например Label - "B" или другой контрол

Далее если например в страничке asp сделать рефренс на "A", тэг, сорс - всё написать в asp - все работает,

Но если в этой страничке попытаться динамически создать контрол "A" - то все внутренние контролы(Label - "B") - не
Инициализируются, т.е. равны null. Я подозреваю, что надо вызвать какойто метод насильного рендеринга, инициализации внутренних контролов.

Подскажите плиз, или хотя бы где прочитать



--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
tol05
Дата 28.4.2007, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 34
Всего: 170



Понятно. Значит так. Твой "сложный" контрол породи от CompositeControl (или Control - по старинке). 
Почитай в MSDN об этом классе. Желательно, чтобы твой контрол еще наследовался от INamingContainer. 
Буквально вчера обсуждался вопрос с проблемами вложенных контролов. см тут
обрати внимание на функции CreateChildControls() и EnsureChildControls()


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Mymik
Дата 28.4.2007, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1474
Регистрация: 12.5.2006
Где: Lamer-центер

Репутация: 50
Всего: 78



SpaceSpace, вызови DataBind -->> Биндятся как сам контрол, так и все child'ы этого контрола.

Добавлено через 53 секунды
замечтался  smile 


--------------------
ICQ ::            857-857
E-mail ::         mymik[at]inbox[dot]ru 
HomaPage ::  http://localhost/

:to_become_senile  :this
PM MAIL WWW ICQ   Вверх
SpaceSpace
Дата 11.5.2007, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 10.4.2007
Где: Самара

Репутация: 3
Всего: 10



Я дико извиняюсь, наверное савсем глупый, но....
опишу проблему подробно...
прошу, отнеситесь к этому серьезно

У меня есть контрол А.ascx, в нем например, лежит Table(хотя там есть и другие контролы),
в клетках которого есть Lable ,button, edit.
В  А.ascx.cs куча кода, который работает с A.Table ->> c Lables ,buttons, edits

Есть контрол B. 
если я в В.ascx ручками пропишу A
<% @Register  tagPrefix="d" tagName="t" src=".."  %>  
и засуну его куда нить 
<d:t runat=".." ID=".." />
то всё работает! 
Но я пытаюсь создать в нем  new А().
Динамически нужно создавать обязательно!!!

При запуске вылетает NullReffrenceException, т.к A.Table не существует! Table прописан в asp файле, я его динамически не создавал!

Неужели мне нужно в коде заново его инициализировать, забивать Id, runat?!!!
Я так понимаю, что ASP  среда парсирует этот файл .ascx и сама инициализирует все компоненты, которые я добросовестно ручками записал.

Внимание вопрос.
Какой контрол должен быть наследован от INamingContainer?(A или B?)
Куда нужно вставить CreateChildControls() или EnsureChildControls() (я вообще сомневаюсь в  пригодности этих методов в данном случае), чтобы инициализация контролов
(которые, мать их, должны уже быть инициализированы) прошла успешно?

Я подозреваю, что тут какая-то байда с порядком вызова обработчиков, и тот который должен прочитать А.ascx, и создать всё, что там положено - соответственно не читает и не создает, и когда подходит очередь выполняться коду A.ascx.cs (в PageLoad, например) - ни один из компонентов A.ascx еще не создан.







--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
Mymik
Дата 11.5.2007, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1474
Регистрация: 12.5.2006
Где: Lamer-центер

Репутация: 50
Всего: 78



SpaceSpace, а ты не можешь так просто создать объект класса A и жить себе спокойно. Тебе нужно будет загрузить контрол
К примеру вот так вот -->>
Код

UserControl control = new UserControl();
control = control.LoadControl("~/bla_bla.ascx");

потом преобразовать  привести его к твоему классу и тогда уже обращаться к своему классу. А иначе ты просто создаешь класс... а так тебе нужно еще с ascx надо связатся...
Ну и естественно после этого засунуть этот UserControl в смою страницу.

Добавлено через 5 минут и 51 секунду
Вообще, как я понимаю asp.net. Так ты вообще создаешь объект страницы (aspx/ascx) а этот класс в свою очередь наследуется от behind-code. Ну конечно сказать, что xml унаследован от C# кода  smile  это круто. Но это если так, просто, ну представить что такое было б возможным :о).
А класс который находится в behind-code попросту обычный класс... Сам по себе он бесполезен. Ну и доступа к элементам что находятся на страницы соответственно не имеет.

P.S. а если тебе нужно просто загрузить контрол. То либо как я выше написал загрузить в объект и выгрузить на страницу. Либо можно через 
Код

Page.Controls.Add(Page.LoadControl("~/bla_bla.ascx"));


Это сообщение отредактировал(а) Mymik - 11.5.2007, 14:19


--------------------
ICQ ::            857-857
E-mail ::         mymik[at]inbox[dot]ru 
HomaPage ::  http://localhost/

:to_become_senile  :this
PM MAIL WWW ICQ   Вверх
SpaceSpace
Дата 14.5.2007, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 10.4.2007
Где: Самара

Репутация: 3
Всего: 10



2Mymik, спасибо за понимание.

<-- Ну конечно сказать, что xml унаследован от C# кода    это круто. Но это если так, просто, ну представить что такое было б возможным :о).-->
А так хотелось smile

Вообще задача следующая, теперь как я понимаю вообще не реализуемая smile

Нужно в GridView или Repeater или еще что нибудь, динамически засунуть шаблон вывода, т.е. уже созданный контрол, которые я пытаюсь динамичеки засунуть в TemplateItem соответствующих GridView или Repeater.

Подскажите пожалуйста, может быть уже есть какое - нибудь решение для этой проблемы ?



--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
tol05
Дата 14.5.2007, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 34
Всего: 170



покажи код.


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Mymik
Дата 14.5.2007, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1474
Регистрация: 12.5.2006
Где: Lamer-центер

Репутация: 50
Всего: 78



Цитата(SpaceSpace @  14.5.2007,  08:45 Найти цитируемый пост)
2Mymik, спасибо за понимание.

Обращайтесь еще  smile 
Цитата(SpaceSpace @  14.5.2007,  08:45 Найти цитируемый пост)
Нужно в GridView или Repeater или еще что нибудь, динамически засунуть шаблон вывода, т.е. уже созданный контрол, которые я пытаюсь динамичеки засунуть в TemplateItem соответствующих GridView или Repeater.

если очень сильно захотеть... то можно и ITemplate подсовывать свой  smile 
Это немного муторно. Но при большом и чистом желании конечно же можно сделать.
Допустим у меня есть Repeater на моей странице (взял его, потому что он самый легкий).
Код

<asp:Repeater ID="repTest" runat="server" />

А теперь чтобы задать динамически свой ItemTemplate к нему. Нам нужно создать отдельный класс, который будет реализовывать ITemplate.
Допустим это будет
Код

sealed class DefaultTemplate : ITemplate
{
    /* Обязательный метод, который нам и создаем template*/
    void ITemplate.InstantiateIn(Control owner)
    {
        owner.Controls.Add(new LiteralControl(DateTime.Today.ToShortDateString()));
        owner.Controls.Add(new LiteralControl("<br/>"));
    }
}

Ну а в коде самой страницы мы напишем вот такой не хитрый код
Код

        /* Создаем Template */
        ITemplate template = new DefaultTemplate();
        /* Создаем контрол */
        Control container = new Control();
        /* Биндимся */
        template.InstantiateIn(container);
        /* Присваиваемся */
        repTest.ItemTemplate = template;
        /* Биндимся */
        repTest.DataSource = new int[10];
        repTest.DataBind();


Добавлено через 3 минуты и 2 секунды
Да, ну и естественно ты туда можешь засовывать не только LiteralControl Но и другие контролы...


--------------------
ICQ ::            857-857
E-mail ::         mymik[at]inbox[dot]ru 
HomaPage ::  http://localhost/

:to_become_senile  :this
PM MAIL WWW ICQ   Вверх
SpaceSpace
Дата 14.5.2007, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 10.4.2007
Где: Самара

Репутация: 3
Всего: 10



Засада заключается в том, что непонятно как присвоить этому templat'y
Contaner.DataItem, чтобы этот шаблон получал от репитера или Грида ту строку, которую
он должен успешно отобразить

а т.к исходный DataSEt может быть любой, то задача поистине нетривиальна.

Нужно как-то умодриться давать шаблону ссылку на DataItem , который нужно будет привести к GridViewRow

.... smile 
делать это нужно будет через задницу

есть способ легче ?


--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
Mymik
Дата 14.5.2007, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1474
Регистрация: 12.5.2006
Где: Lamer-центер

Репутация: 50
Всего: 78



И все же лучше использовать PlaceHolder и какой-нибудь флаг при бинди Repeater.
Т.е. у тебя будет какой-нибудь флаг в DataSource и по нему ты будешь определять показывать или скрывать данные.
Код

<asp:PlaceHolder Visible='<%# !Convert.ToBoolean(Eval("AdminOnly")) %>' runat="server">
 <!-- А тут данные доступные только для администратора -->
</asp:PlaceHolder>



--------------------
ICQ ::            857-857
E-mail ::         mymik[at]inbox[dot]ru 
HomaPage ::  http://localhost/

:to_become_senile  :this
PM MAIL WWW ICQ   Вверх
Mymik
Дата 14.5.2007, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1474
Регистрация: 12.5.2006
Где: Lamer-центер

Репутация: 50
Всего: 78



Цитата(SpaceSpace @  14.5.2007,  11:14 Найти цитируемый пост)
Засада заключается в том, что непонятно как присвоить этому templat'y
Contaner.DataItem, чтобы этот шаблон получал от репитера или Грида ту строку, которую
он должен успешно отобразить

А на кой нам нужен тогда ItemDataBound ???
Опять таки изменим несколько наш DefaultTemplate
Код

sealed class DefaultTemplate : ITemplate
{
    void ITemplate.InstantiateIn(Control owner)
    {
        Label title = new Label();
        title.ID = "lblTitle";
        owner.Controls.Add(title);
        owner.Controls.Add(new LiteralControl("<br/>"));
    }
}

Мы добавили сюда ID элемента.
Так же прикрепим к нашему Repeater к событию OnItemDataBound обработчик
Код

<asp:Repeater ID="repTest" OnItemDataBound="repTest_ItemDataBound" runat="server" />


А в behind-code мы поставим вот такой вот код
Код

    protected void Page_Load(object sender, EventArgs e)
    {
        /* Определение template как и раньше */
        ITemplate template = new DefaultTemplate();
        Control container = new Control();
        template.InstantiateIn(container);
        repTest.ItemTemplate = template;
        /* Создание данных */
        System.Collections.Generic.List<string> source = new System.Collections.Generic.List<string>();
        for(int i = 0; i < 5; i++)
            source.Add(i.ToString());
        /* Прикрепление данных */
        repTest.DataSource = source;
        repTest.DataBind();
    }

    protected void repTest_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        /* Ну а тут вот ты можешь уже преобразовывать e.Item.DataItem к DataRow и проверять, есть ли там такие данные или нет И засовывать эти данные.  */
        if (e.Item.DataItem != null)
            (e.Item.FindControl("lblTitle") as Label).Text = (string)e.Item.DataItem;
    }




--------------------
ICQ ::            857-857
E-mail ::         mymik[at]inbox[dot]ru 
HomaPage ::  http://localhost/

:to_become_senile  :this
PM MAIL WWW ICQ   Вверх
SpaceSpace
Дата 15.5.2007, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 10.4.2007
Где: Самара

Репутация: 3
Всего: 10



2Mymik
Насчет ItemDataBound -  я этот метот и имел в виду, когда говорил, что через задницу smile
точнее не метод а событие,
дело в том, что "как-нибудь" можно реализовать,
а вот изящно, чтоб другие поняли - проблема,
я у себя в конторе предлагаю перекроить подход к разработке ASP(тема обсуждаемая в этом топе)
Соответственно и предлагаю мощно использовать шаблоны и вообще что только можно сделать custom
Одно дело - я один такой умный, другое - заразить еще человек 10 этим подходом,
Поэтому тема и обсуждается, я щас покорплю над ней, подытожу на чем мы остановились.
Затем надеюсь на дальнейшее плодотворное сотрудничество, может удасться сделать легче....

Это сообщение отредактировал(а) SpaceSpace - 15.5.2007, 07:36


--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
SpaceSpace
Дата 15.5.2007, 09:49 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 10.4.2007
Где: Самара

Репутация: 3
Всего: 10



2Mymik

Не подскажеш, как проделать теже манипуляции с GridView?

Добавлено через 5 минут и 20 секунд
Единственное что приходит в голову - делать через задницу smile

            System.Web.UI.WebControls.TemplateField tf = new TemplateField();
            tf.ItemTemplate=...
есть другой путь?


--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
Mymik
Дата 15.5.2007, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1474
Регистрация: 12.5.2006
Где: Lamer-центер

Репутация: 50
Всего: 78



Цитата(SpaceSpace @  15.5.2007,  07:29 Найти цитируемый пост)
Насчет ItemDataBound -  я этот метот и имел в виду, когда говорил, что через задницу

если следовать логике данного высказывания, то можно подумать, что метод Page_Load тоже решение через задницу. А использование InvokeMember тоже плохой тон,- зачем описывать метод, давайте лучше как-то по другому будем определять. Или возьмем Type и будем вызывать все методы класса, пока не достигнем нужного результата. 
это мое ИМХО. Пока что мне кажется, что твое решение притянуто за уши. Сколько раз ты встречал такие таски, где у тебя нет существующего tamplate (за исключением когда ты пишешь свой контрол. Да и то, там люди используют классы реализующий INamingContainer и тем самым возлагают проблемы написания template на пользователя). Я не говорю, что твое решение это плохо -- исследовать возможности языка это очень похвальная миссия, тем более такой платформы как .NET Framework. Но целесообразно ли это ??? Т.е. зачем тебе это (написание такого контрола, а не исследование языка) ??? Приведи какой-нибудь надуманный, но при этом конкретный пример, когда твое творение может быть использовано ???
Перед тем как писать код, нужно всегда думать о его целесообразности. Можно написать обычный цикл, а можно пойти рекурсивным методом. На тогда надо представлять, сколько памяти занимает один виток твое рекурсии, и умножить на примерное количество ветков и еще раз умножить на примерное количество посещаемости страницы. И тогда ты сможешь понять, целесообразно ли писать рекурсивный метод работы над 10 объектами сразу при xml данных размером в 3Mb (у меня была такая ситуация. До того как я подхватил проект, реализовывалась рекурсивная работа над xml данными при обходе их и просчете всех возможных вариантов и поиска следующей ячейки, но это было когда xml максимум 60 node'ов имел. А когда он расширился до 15к ячеек при нагрузке на сервер где-то 30 запросов в секунду... Та даже при 3 запросах он уже умирал. Просто вылетал StackOverflow).
вот и в твоем случаи. целесообразно ли будет выполнять столь громоздкие вычисления по просчету количества колонок, созданию объектов классов для template... А если колонок будет "ой как много"...


Цитата(SpaceSpace @  15.5.2007,  07:29 Найти цитируемый пост)
дело в том, что "как-нибудь" можно реализовать

У каждого метода всегда есть конкретные задачи, которые он должен выполнять. Шаг влево, шаг вправо -- расстрел.

Цитата(SpaceSpace @  15.5.2007,  09:49 Найти цитируемый пост)
Единственное что приходит в голову - делать через задницу smile

            System.Web.UI.WebControls.TemplateField tf = new TemplateField();
            tf.ItemTemplate=...
есть другой путь? 

э-э-э.. Когда ты создаешь GridView, ты описываешь колонки, так ???
Ты описываешь template для каждой колонки что тебе нужно, так ???
Вот собственно и ответ.


--------------------
ICQ ::            857-857
E-mail ::         mymik[at]inbox[dot]ru 
HomaPage ::  http://localhost/

:to_become_senile  :this
PM MAIL WWW ICQ   Вверх
SpaceSpace
Дата 15.5.2007, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 10.4.2007
Где: Самара

Репутация: 3
Всего: 10



2Mymik

Спасибо за критику.

Таск следующего вида:
Есть сайт.
Много страниц.
На каждой странице - репитер гридвью и тд.
на одну строку - один Template/
До тех пор, пока не изобрели мониторы с высотой в километр, я думаю
можно не боятся оверфлова из-за перегрузки, мы имеем дело всего лишь с визуализацией текстовых данных из БД, посредством Вью или репитера

Как происходит процесс разработки(абстактно):
берем тз, делаем Бд, делаем Слои(БД и тд)
делаем слой web.
Потом для каждой более менее сложной задачи дизайним Контролы (много контров).

В чем мысль(жду критики):
Делаем 2 контрола(репитер и гридвью)
Делаем шаблоны вывода(что обсуждаем так рьяноsmile)
Далее этим custom репитерам или грид вью указываем какой шаблон использовать.
Сам шаблон содержит весь дизайн и логику работы с БД(не доступа, а именно работы(constriants например))
ВсЁ!

Смысл в том, чтобы унифицировать использование репитеров или гридвью,
и абстагироваться от слоя доступа к данным.
Templates работают через DataItem,
Биндится весь сорс к вью, например,
отсюда экономия времени на  рутинную настройку(пара-тройка методов c каждого Template)

жду ответа smile


--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Любитель
Mymik
mr.DUDA

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Любитель, Mymik, mr.DUDA.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка под ASP.NET | Следующая тема »


 




[ Время генерации скрипта: 0.0601 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.