Usuário com melhor resposta
Controle Customizado com Atributos

Pergunta
-
Boa Noite, gostaria de saber como fazer um controle customizado (sem AJAX ou outro recurso - puro ASP.net) que possa receber atributos próprios e containers.
Quero um resultado parecido com um Panel, por exemplo.
<asp:Panel Id="panel1" visible="true">
<asp:Label Id="title1" Text="Título" />
</asp:Panel>Quero que meu componente alcance esse resultado, podendo ter atributos como "Visible", "Width", "Style" (e quaisquer outros que eu crie como "Index" por exemplo).
E ainda, veja que o painel é capaz de receber componente como um "container", como a Label que coloquei. Então meu componente precisa ter abertua e fechamanto e agregar as tags internas a ele... como um Painel, um Repeater, que tem "ItemTemplate" e outro atributos que não são passados por "=", mas entre as tags "<>....</>".
Qualquer ajuda é bem vinda.
Respostas
-
Ola,
Acho que achei um fórum com a sua mesma duvida... infelizmente não estou com tempo para testar, mas se der certo de um retorno explicando o que você fez, para que os próximos que lerem esse tópico puderem solucionar o problema ok ?
http://stackoverflow.com/questions/11210763/expose-nested-html-property-on-asp-net-usercontrol
Microsoft Community Contributor
- Marcado como Resposta SammuelMiranda domingo, 9 de fevereiro de 2014 00:47
Todas as Respostas
-
-
Sim Rodrigo, a ideia é cria um Web UserControl, porém eu preciso que ele responda a atributos que eu criar (preencher as propriedades com o valor escrito no script (exemplo: um TextBox que foi declarado na página como <asp:TextBox id="Teste" runat="server" Enabled="false" Text="Isso Ai" />, ao ser carregado no servidor você pode coletar o valor da propriedade "Teste.Enabled" que ele retornará o valor "False").
E outra, como no exemplo que eu dei do Painel, em cada página o painel tem "filhos" diferentes. Na página 1 eu posso colocar 2 labels nele, na página 2 eu posso colocar 3 textboxes e 1 image... e assim por diante, porque o controle "Panel" consegue coletar todos os controle declarados entre "<asp:Panel> ... </asp:Panel>" e adicioná-los como controles. É isso.
Basicamente meu componente tem que ter um cabeçalho e um rodapé, e o conteúdo entre o cabeçalho e o rodapé NÃO ESTARÁ NO COMPONENTE, mas sim na página onde ele se encontra.
Espero ter me explicado melhor.
-
Ola,
Voce pode usar a propriedade Attribute["atributoHtml"]
Por exemplo uma tag <asp:textbox id="textBox1" runat="server" data-cor="azul"/> voce poderia ler o atribuito da seguinte forma no server-side:
string cor = textBox1.Attribute["data-cor"];
lembrando que por "convenção" no html5 as tags customizadas devem começar com o prefixo "data-"http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.attributes%28v=vs.110%29.aspx
http://html5doctor.com/html5-custom-data-attributes/
Microsoft Community Contributor
-
Rui, muito obrigado pela resposta - isso já resolve metade do meu problema :)
Agora eu só preciso que meu componente aceite a declaração de sub-componentes - exatamente como o Asp:Panel, Asp:Repeater, asp:DropdownList ... todos que você pode declarar os sub-componentes variavelmente, sem deixar escrito no UserControl- entende?
Obrigado pela ajuda.
-
Uhm... acho que seria melhor você detalhar um pouco mais o que pretende, dependendo do que for, a solução pode ser muito complicada o que não valeria a pena...
Nesse meio tempo... veja se esse exemplo lhe ajuda:
<%@ Page Language="C#" AutoEventWireup="true"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> class Usuario { public string Nome { get; set; } public string Cidade { get; set; } public string Idade{ get; set; } public static Usuario Load(Control control) { var usuario = new Usuario(); foreach (Control child in control.Controls) { if (child is WebControl) { var input = (child as WebControl); var dataField = input.Attributes["data-field"].ToLower(); switch (dataField) { case "nome": usuario.Nome = (input as TextBox).Text; break; case "cidade": usuario.Cidade = (input as TextBox).Text; break; case "idade": usuario.Cidade = (input as TextBox).Text; break; default: continue; } } } return usuario; } } protected void Unnamed5_Click(object sender, EventArgs e) { var usuario = Usuario.Load(usuarioPanel); ScriptManager.RegisterStartupScript(this, this.GetType(), "alerta", String.Format("alert('Nome: {0}');", usuario.Nome), true); } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:Panel runat="server" ID="usuarioPanel"> <asp:TextBox runat="server" data-field="Nome" /> <asp:TextBox runat="server" data-field="Cidade" /> <asp:TextBox runat="server" data-field="Idade" /> </asp:Panel> <asp:Button Text="text" runat="server" onclick="Unnamed5_Click" /> </div> </form> </body> </html>
Microsoft Community Contributor
-
Ok Rui, vou te mostrar o que procuro exatamente, com total descrição....
Digamos que o ASPX do meu controle seja:
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="tabblock.ascx.vb" Inherits="CentralWeb.tabblock" %> <ul class="tabs" data-index="0"> <li> <input type="radio" name="tabs" id="tab_id" /><label for="tab_id">Identificação</label> <div class="tabcontainer"> AQUI É O PRIMEIRO </div> </li> <li> <input type="radio" name="tabs" id="tab_user" /><label for="tab_user">Responsável</label> <div class="tabcontainer"> AQUI É O SEGUNDO </div> </li> </ul>
Pois bem, assim como em um repeater, onde você pode declarar ItemTemplate, FooterTamplate etc... eu preciso que eu possa colocar, em uma página, o meu controle assim:
<%@ Register TagPrefix="uc" TagName="bindedinfo" Src="~/content/tabblock.ascx" %> <uc:tabblock id="tab1" runat="server" data-index="0"> <primeiro> <asp:Repeater id="search_results" runat="server" /> </primeiro> <segundo> <asp:TextBox Id="p1" runat="server" /> <asp:Button id="sercher" runat="server" text="procurar..." /> </segundo> </uc:tabblock>
Veja que, dentro do "<uc:tabblock></uc:tabblock>" eu tenho sub-tags (assim como o ItemTemplate em um repeater) que será carregado no espaço onde escrevi "AQUI É O PRIMEIRO" e "AQUI É O SEGUNDO".
Ou seja, ele vai adicionar qualquer coisa que eu escrever e renderizar o começo do componente, então tudo que estiver em <primeiro> depois o meio do componente, depois tudo que estiver dentro de <segundo> e depois o fim do componente; assim como um Repeater redereriza qualquer coisa que você digitar em HeaderTemplate, depois tudo que você digitar em ItemTemplate (para cada item no DataSource - isso não precisa para o meu caso) e depois tudo que estiver dentro de FooterTemplate.
-
Ola,
Acho que achei um fórum com a sua mesma duvida... infelizmente não estou com tempo para testar, mas se der certo de um retorno explicando o que você fez, para que os próximos que lerem esse tópico puderem solucionar o problema ok ?
http://stackoverflow.com/questions/11210763/expose-nested-html-property-on-asp-net-usercontrol
Microsoft Community Contributor
- Marcado como Resposta SammuelMiranda domingo, 9 de fevereiro de 2014 00:47
-
Excelente Rui - é isso mesmo.
Tem 2 respostas nesse tópico do Stackoverflow, um usando InnerProperty e o outro usando Template... acho que vou acabar usando ambos os casos em meu programa... muito obrigado por tomar tempo para encontrar isso, ajudou muito.
-
Excelente Rui - é isso mesmo.
Tem 2 respostas nesse tópico do Stackoverflow, um usando InnerProperty e o outro usando Template... acho que vou acabar usando ambos os casos em meu programa... muito obrigado por tomar tempo para encontrar isso, ajudou muito.
Imagina, confesso que depois que entendi o problema tambem fiquei curioso...
Nao esquece depois de compartilhar com a gente as suas descobertas... qual funcionou melhor e o porque ta ?
Microsoft Community Contributor
-
Vou sim ... ainda não postei nada porque tem mais coisas para colocar no projeto antes de eu chegar no componente - postei a pergunta no fórum com alguma antecedência para poder ter uma resposta a tempo - e já tive :)
Assim que eu chegar nessa parte vou compartilhar a classe.