Как включить дополнительную разметку во внутреннее свойство «Содержимое» ASP.Net WebControl? - PullRequest
4 голосов
/ 30 апреля 2010

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

Я написал всплывающее окно jQuery, которое я упаковал как WebControl и IScriptControl. Последний шаг - это возможность написать разметку в тегах моего элемента управления. Я использовал атрибут InnerProperty несколько раз, но только для включения списков строго типизированных классов.

Вот моя собственность в WebControl:

[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public something??? Content
{
   get
   {
      if (_content == null)
      {
         _content = new something???();
      }
      return _content;
   }
}
private something??? _content;

Вот HTML-разметка того, что мне нужно:

   <ctr:WebPopup runat="server" ID="win_Test" Hidden="false" Width="100px" Height="100px"
      Modal="true" WindowCaption="Test Window" CssClass="window">
      <Content>
         <div style="display:none;">
            <asp:Button runat="server" ID="Button1" OnClick="Button1_Click" />
         </div>
         <%--Etc--%>
         <%--Etc--%>
      </Content>
   </ctr:WebPopup>

К сожалению, я не знаю, какого типа должно быть мое свойство Content. Мне нужно скопировать UpdatePanel ContentTemplate.

.

EDIT : Таким образом, следующее позволяет автоматически создавать контейнер Template, но не отображаются элементы управления, что не так с тем, что я делаю?

[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ITemplate Content
{
    get
    {
        return _content;
    }
    set
    {
        _content = value;
    }
}
private ITemplate _content;

EDIT2 : переопределение CreateChildControls позволяет отображать элементы управления в ITemplate:

protected override void CreateChildControls()
{
   if (this.Content != null)
   {
      this.Controls.Clear();
      this.Content.InstantiateIn(this);
   }
   base.CreateChildControls();
}

К сожалению, теперь я не могу получить доступ к элементам управления в ITemplate из файла codebehind в файле. То есть если я поставлю кнопку в своей метке, как это:

<ctr:WebPopup runat="server" ID="win_StatusFilter">
   <Content>
      <asp:Button runat="server" ID="btn_Test" Text="Cannot access this from code behind?" />
   </Content>
</ctr:WebPopup>

Я тогда не могу получить доступ к btn_Test из кода:

protected void Page_Load(object sender, EventArgs e)
{
   btn_Test.Text = "btn_Test is not present in Intellisense and 
      is not accessible to the page. It does, however, render correctly.";
}

EDIT3 : ИСПРАВЛЕНО! Правка 2 является правильным решением. Просто Visual Studio 2010 была болью в ягодицах. Закрыл приложение и снова открыл его, и все мои элементы управления в свойстве Content были доступны на странице.

EDIT4 : Правка 2 не устранила проблему. Я уже пробовал атрибут [TemplateInstance(TemplateInstance.Single)], прежде чем кто-то упомянул об этом, однако в то время я не думал, что это что-то изменило. Похоже, Visual Studios 2010 просто странно сегодня.

Поскольку я удалил тег и он продолжал работать, я предположил, что атрибут не имеет значения. С тех пор, как мы снова вернулись к коду, элементы управления стали недоступны. Добавление атрибута обратно позволило ему все работать и сделать элементы управления доступными на стороне сервера. БЕЗУМИЕ . Я приму ответ Брайана, поскольку он упомянул исправление раньше всех.

Ответы [ 2 ]

5 голосов
/ 30 апреля 2010

общедоступный контент ITemplate

, который затем вы отображаете в пользовательском интерфейсе, как:

Label label = new Label();
this.Content.InstantiateIn(label);

//Render label

РЕДАКТИРОВАТЬ: убедитесь, что шаблон также определяет

[TemplateInstance(TemplateInstance.Single)]

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

1 голос
/ 04 мая 2010

Вы должны попытаться использовать это:

win_StatusFilter.FindControl("btn_Test") // this will be a Control
win_StatusFilter.FindControl("btn_Test") as Button // this will be a Button if control found, otherwise it will be null.

В противном случае вы должны определить некоторые свойства для вашего элемента управления, как в этой статье: http://msdn.microsoft.com/ru-ru/library/36574bf6%28v=VS.90%29.aspx


Обновление: В соответствии с замечаниями в этой статье о свойстве ContentTemplate элемента UpdatePanel:

http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.contenttemplate(v=VS.90).aspx

элементы управления ContentTemplate можно получить благодаря значению TemplateInstanceAttribute (UpdatePanel.ContentTemplate имеет TemplateInstance.Single).

Таким образом, вы должны использовать только этот код:

[PersistenceMode(PersistenceMode.InnerProperty)] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
[TemplateInstance(TemplateInstance.Single)]
public ITemplate Content

Более подробная информация по адресу:

http://msdn.microsoft.com/ru-ru/library/system.web.ui.templateinstanceattribute(v=VS.90).aspx

...