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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание Web Server Control, наследуемся от Control, INamingContainer 
V
    Опции темы
Wanderer2019
Дата 26.4.2007, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 17



И снова я, и опять про контролы =)
От предыдущего поста и описанной в нем реализации пришлось отказаться... 
Решил писать свой контрол наследованные от Control и INamingContainer. Используя это, его можно засунуть в dll + вытащить на тулбар студии, что является весьма полезной вещью.

Но вот наткнулся на такую непонятку... 
Мой контрол содержит в себе TreeView. С ним собстно и ведется работа. 
При вытаскивании контрола на aspx страницу он почему то внутрь моего контрола пишет этот TreeView. т.е. мой контрол является как бы контейнером. Так и должно быть? Но это еще пол беды.. самое плохое, что при возникновении события вылетает такой вот Exception =(
Код

Multiple controls with the same ID 'ctl00' were found. FindControl requires that controls have unique IDs.

вот тут я совсем не понияю в чем дело.. т.е. получается, что дизайнер сам добавляет этот TreeView внутрь моего контрола - контейнера, так он еще и путается в чем то???
PM ICQ MSN   Вверх
tol05
Дата 26.4.2007, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Класс, реализующий INamingContainer становится контейнером имен для всей своих внутренних контролов. Обеспечивает уникальность имен.
Например, если ты на странице выложишь два своих юзер-контрола c ID MyControl1 и MyControl2, то TreeView у них будут иметь разные UniqueID, такие как MyControl1$TreeView1 и MyControl2$TreeView1. 
так что твой класс - контейнер для TreeView.

По поводу exception - покажи код класса и страницы.


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


Опытный
**


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

Репутация: 1
Всего: 17



Цитата(tol05 @  26.4.2007,  17:08 Найти цитируемый пост)
Класс, реализующий INamingContainer становится контейнером имен для всей своих внутренних контролов. Обеспечивает уникальность имен.
Например, если ты на странице выложишь два своих юзер-контрола c ID MyControl1 и MyControl2, то TreeView у них будут иметь разные UniqueID, такие как MyControl1$TreeView1 и MyControl2$TreeView1. 
так что твой класс - контейнер для TreeView.

По поводу exception - покажи код класса и страницы. 


Убрал наследвание от INamingContainer и ошибка пропала... однако внутри Mycontrol по прежнему продолжает появляться тег TreeView....  можно вообще как то этого избежать??? 

PM ICQ MSN   Вверх
tol05
Дата 27.4.2007, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Wanderer2019, 
Цитата

покажи код класса и страницы


Без кода трудно что-то понять.
вот например, набрал такой код:
Код

using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyControlNamespace
{
  public class MyControl :Control
  {
    TreeView tv;

    public TreeView Tree
    {
      get { return tv; }
      set { tv = value; }
    }

    public MyControl()
    {
      tv = new TreeView();
      //
      // TODO: Add constructor logic here
      //
    }
  }
}


скомпилил в dll, подключил к ToolBar, выложил на страницу
Код

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register Assembly="MyControl" Namespace="MyControlNamespace" TagPrefix="cc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <cc1:MyControl ID="MyControl1" runat="server">
      </cc1:MyControl>


    </div>
    </form>
</body>
</html>


Код сгенерировала студия. Нет никаких вложенных тегов


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


Опытный
**


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

Репутация: 1
Всего: 17



ну вот собстно такой код:
Код

    [DefaultEvent("SelectedNodeChanged")]
    public class DictionaryView: Control
    {
        private TreeView ItemsTree;
        private Label ErrorsInf;
        #region Events
        public event EventHandler SelectedNodeChanged;
        protected void OnSelectedNodeChanged(object sender, EventArgs e)
        {
            if (SelectedNodeChanged != null)
            {
                SelectedNodeChanged(((TreeView)sender).SelectedNode, e);
            }

        #endregion
        #region Properties
        private string _DVURL;
        public string DVURL
        {
            set { _DVURL = value; }
            get { return _DVURL; }
        }
        private string _BaseName;
        public string BaseName
        {
            set { _BaseName = value; }
            get { return _BaseName; }
        }
        public enum Dictionarys
        {
            TypesDictionary = 1,
            EmployeeDictionary = 2,
            ContragentsDictionary = 3,
            CategoryDictionary = 4
        };
        private Dictionarys _DictionaryType;
        public Dictionarys DictionaryType
        {
            get
            {
                return _DictionaryType;
            }
            set
            {
                _DictionaryType = value;
            }
        }
        private int _height=300;
        private int _width=120;
        private int _size=12;
        #endregion
        protected override void CreateChildControls()
        {
            ErrorsInf = new Label();
            Controls.Add(ErrorsInf);
            ItemsTree = new TreeView();
            ItemsTree.ShowLines = true;
            ItemsTree.SelectedNodeChanged += new EventHandler(OnSelectedNodeChanged);
            ItemsTree.Width = _width;
            ItemsTree.Height = _height;
            ItemsTree.ParentNodeStyle.Font.Size = _size;
            ItemsTree.ParentNodeStyle.ForeColor = Color.Black;
            ItemsTree.SelectedNodeStyle.Font.Size = _size;
            ItemsTree.SelectedNodeStyle.ForeColor = Color.Black;
            ItemsTree.SelectedNodeStyle.BackColor = Color.BurlyWood;
            ItemsTree.RootNodeStyle.Font.Size = _size;
            ItemsTree.RootNodeStyle.ForeColor = Color.Black;
            ItemsTree.LeafNodeStyle.Font.Size = _size;
            ItemsTree.LeafNodeStyle.ForeColor = Color.Black;
            ItemsTree.NodeStyle.Font.Size = _size;
            Controls.Add(ItemsTree);
        }

        public void FillTree()
        {
            
        }
        public DictionaryView()
        {
            EnsureChildControls();

        }
    } 


по размещении на форме получается вот что:
Код

<cc1:dictionaryview id="DictionaryView1" runat="server" basename="имя_базы"
            dictionarytype="EmployeeDictionary" dvurl="УРЛ">
</cc1:dictionaryview>


и все бы отлично.. но после манипуляций (запуск приложения) в коде появляется вот что:
Код

<cc1:dictionaryview id="DictionaryView1" runat="server" basename="имя_базы"
            dictionarytype="EmployeeDictionary" dvurl="УРЛ"><asp:Label runat="server"></asp:Label>
<asp:TreeView runat="server" ShowLines="True" Width="120px" Height="300px">
<NodeStyle Font-Size="12pt"></NodeStyle>

<RootNodeStyle ForeColor="Black" Font-Size="12pt"></RootNodeStyle>

<SelectedNodeStyle BackColor="BurlyWood" ForeColor="Black" Font-Size="12pt"></SelectedNodeStyle>

<ParentNodeStyle ForeColor="Black" Font-Size="12pt"></ParentNodeStyle>

<LeafNodeStyle ForeColor="Black" Font-Size="12pt"></LeafNodeStyle>
</asp:TreeView>
</cc1:dictionaryview>


откуда оно берется ???
PM ICQ MSN   Вверх
Wanderer2019
Дата 27.4.2007, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 17



Более того.. после изменения одного из свойств.. внутри тега, описывающего непосредственно мой компонент появляются еще теги TreeView... т.е. под каждый набор свойств студия дописывает туда свой TreeView.... 
Код

 <cc1:DictionaryView ID="DictionaryView1" runat="server" BaseName="ИмяБазы" DictionaryType="ContragentsDictionary" DVURL="УРЛ" OnSelectedNodeChanged="DictionaryView1_SelectedNodeChanged1">
            <asp:Label runat="server"></asp:Label>
            <asp:TreeView runat="server" Height="10px" ShowLines="True" Width="20px">
                <NodeStyle Font-Size="12pt" />
                <RootNodeStyle Font-Size="12pt" ForeColor="Black" />
                <SelectedNodeStyle BackColor="BurlyWood" Font-Size="12pt" ForeColor="Black" />
                <ParentNodeStyle Font-Size="12pt" ForeColor="Black" />
                <LeafNodeStyle Font-Size="12pt" ForeColor="Black" />
            </asp:TreeView>
            <asp:Label runat="server"></asp:Label>
            <asp:TreeView runat="server" Height="10px" ShowLines="True" Width="20px">
                <NodeStyle Font-Size="12pt" />
                <RootNodeStyle Font-Size="12pt" ForeColor="Black" />
                <SelectedNodeStyle BackColor="BurlyWood" Font-Size="12pt" ForeColor="Black" />
                <ParentNodeStyle Font-Size="12pt" ForeColor="Black" />
                <LeafNodeStyle Font-Size="12pt" ForeColor="Black" />
            </asp:TreeView>
        </cc1:DictionaryView>


 smile 
PM ICQ MSN   Вверх
tol05
Дата 27.4.2007, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Значит о первом посте 
Цитата
откуда оно берется 


У тебя в конструкторе стоит EnsureChildControls(). Она проверяет, созданы ли дочерние контролы и если нет - создает их (вызывает CreateChildControls())
Когда ты что-то меняешь в PropertyWindows, студия создает объект каждый раз заново (это и для WinForms также. Это работа визуального дизайнера так устроена). Поэтому у тебя и вызывается конструктор, а дальше - EnsureChildControls(). И значения тегов страницы те же, что и в CreateChildControls(). Чудес не бывает.

Все нормально. Ты ведь через PropertyWindows инициализируешь какие-то свойства контрола, должна же где-то хранится эта инфформация? Вот она со страницей и хранится, не в dll же студии писать? smile

Второй пост: клонирование.
С клонированием дочерних тегов: прикольно. smile

Во-первых ты не проверяешь созданы ли уже дочерние контролы или еще нет. А для этого от Control у тебя есть свойство ChildControlsCreated. Как EnsureChildControls() узнает созданы ли дочерние контролы? Смотрит это свойство!

во-вторых. Ты в конструкторе вызываешь виртуальную EnsureChildControls(). От этого булшит.
Убрал я все из конструктора. Нет никаких внутренних тегов. (конструктор по умолчанию нечиго не содержит)
Ее нужно использовать тогда, когда ты собираешься работать с дочерними контролами. Связок между твоим контроломи дочерними я не нашел, поэтому ткнул this.EnsureChildControls() в свойства.
Теперь когда ты просто кидаешь контрол на форму, он не содержит нечего лишнего. Если иницициализируешь дочерние контролы через дизайнер, то тогда инфа будет хранится на странице, как положено.

Код:
Код

namespace CustomTreeViewcontrol
{
  [DefaultEvent("SelectedNodeChanged")]
    public class DictionaryView: Control
    {
        private TreeView ItemsTree;
        private Label ErrorsInf;
#region Events
      public event EventHandler SelectedNodeChanged;
      protected void OnSelectedNodeChanged(object sender, EventArgs e)
      {
        if(SelectedNodeChanged != null)
        {
          SelectedNodeChanged(((TreeView)sender).SelectedNode, e);
        }
      }
#endregion
    
#region Properties
        private string _DVURL;
        public string DVURL
        {
            set
            {
              
              this.EnsureChildControls();
              _DVURL = value;
            }
            get
            {
              this.EnsureChildControls();
              return _DVURL;
            }
        }
        private string _BaseName;
        public string BaseName
        {
            set
            {
              this.EnsureChildControls();
              _BaseName = value;
            }
            get
            {
              this.EnsureChildControls();
              return _BaseName;
            }
        }
        public enum Dictionarys
        {
            TypesDictionary = 1,
            EmployeeDictionary = 2,
            ContragentsDictionary = 3,
            CategoryDictionary = 4
        };
        private Dictionarys _DictionaryType;
        public Dictionarys DictionaryType
        {
            get
            {
                return _DictionaryType;
            }
            set
            {
                _DictionaryType = value;
            }
        }
        private int _height=300;
        private int _width=120;
        private int _size=12;
#endregion
        protected override void CreateChildControls()
        {
          Controls.Clear();
          
            ErrorsInf = new Label();
            Controls.Add(ErrorsInf);
            ItemsTree = new TreeView();
            ItemsTree.ShowLines = true;
            ItemsTree.SelectedNodeChanged += new EventHandler(OnSelectedNodeChanged);
            ItemsTree.Width = _width;
            ItemsTree.Height = _height;
            ItemsTree.ParentNodeStyle.Font.Size = _size;
            ItemsTree.ParentNodeStyle.ForeColor = Color.Black;
            ItemsTree.SelectedNodeStyle.Font.Size = _size;
            ItemsTree.SelectedNodeStyle.ForeColor = Color.Black;
            ItemsTree.SelectedNodeStyle.BackColor = Color.BurlyWood;
            ItemsTree.RootNodeStyle.Font.Size = _size;
            ItemsTree.RootNodeStyle.ForeColor = Color.Black;
            ItemsTree.LeafNodeStyle.Font.Size = _size;
            ItemsTree.LeafNodeStyle.ForeColor = Color.Black;
            ItemsTree.NodeStyle.Font.Size = _size;
            Controls.Add(ItemsTree);
          
          //ChildControlsCreated = true;
        }

        public void FillTree()
        {
            
        }
        public DictionaryView()
        {
        }

      protected override void EnsureChildControls()
      {
        if(!ChildControlsCreated)
        {
          try
          {
            CreateChildControls();
          }
          finally
          {
            ChildControlsCreated = true;
          }
        }
      }
    } 
}


и последнее: для уменьшения геморроя мелкомягкие предлагают использовать CompositeControl вместо Control для составных элементов. Правда только в ASP.NET2.0

Ну, кажись все, я кончил!


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


Опытный
**


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

Репутация: 1
Всего: 17



tol05, 
спасибо за помощь.. разобрался  smile 

однако ввиду необнаруженных возможностей... решил наследоваться от WebControl... по ряду причин оказалось намного удобнее (наличие стандартных свойств и т.д.)
создание контролов переписал как ты указал: через свойства + перегрузка EnsureChildControls(). 
НО! Почему теперь то нельзя засунуть EnsureChildControls в конструктор? все равно ж теперь проверяется CreatedChildControls..., а так все же на форме его сразу видишь.. как перетащил из ToolBox`а... или я не прав??
PM ICQ MSN   Вверх
tol05
Дата 27.4.2007, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



И тебе спасибо.
Цитата

Почему ... нельзя засунуть EnsureChildControls в конструктор

Потому что студия пытается все проимитировать в режиме дизайна, да криво.
Берет код своего класса, строит контролы, а потом тупо парсит теги с HTML страницы (с предыдущего рендеринга), а вдруг ты их ручками дописал? Ну и добавляет их туда же.
Я специально подебагал в той же студии, все нормально сработало, не добавляются лишние дочерние контролы.
Я имею в ввиду, что засунул EnsureChildControls в конструктор

Это сообщение отредактировал(а) tol05 - 27.4.2007, 15:50


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Любитель
Mymik
mr.DUDA

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

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

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


 




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


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

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