none
Incluir UserControl a partir de uma string RRS feed

  • Pergunta

  • Olá pessoal, tudo bem?

    Estou desenvolvendo um "CMS" para a empresa onde trabalho e há a seguinte necessidade: 

    Incluir um UserControl a partir de uma string proveniente do banco. 

    O meu cenário está da seguinte forma: 

    Eu tenho um arquivo ".aspx" único (default.aspx). Ele recebe uma QueryString com o ID da página que deve ser apresentada.

    Quando ela recebe, realiza uma consulta e popula um literal com o HTML salvo no banco.

    Ok, até aqui nenhuma novidade.

    Na página eu defino um "tipo" que é vinculado à um UserControl, com isso eu posso ter vários layouts de páginas, dependendo da necessidade. 

    Mas como a galera não se contenta (haha) surgiu uma nova ideia que não estou conseguindo implementar.

    Dentro do HTML que é populado no Literal pode conter uma string padrão, por exemplo "[ModuloID=15]" e ao detectar (via regex?) eu devo trocar essa string pelo módulo (UserControl) vinculado ao ID 15 e mantendo a posição definida pelo usuário.

    Isso irá possibilitar que o usuário tenha total controle sobre o HTML do site e me libertará de ter que criar, por exemplo, vários tipos de UserControls, às vezes com a mesma funcionalidade (Ex: enviar um e-mail de contato), porém com um HTML muito diferente.

    Em outras palavras o que estou tentando fazer é enfiar um Controle dentro de um literal no page load... Mas acho que isso não rola.

    Consegui fazer algo estranho, mas achei que ficou um tremendo gato, vejam:

    string patternModule = @"\[(t|T)ype(t|T)ext(i|I)(d|D)=(\d*)\]";
                foreach (Match match in Regex.Matches(texto, patternModule, RegexOptions.IgnoreCase))
                {
                    Int32 ID = Int32.Parse(match.Groups[5].Value);

                    string htmlCode = "";
                    using (WebClient client = new WebClient())
                    {
                        client.Encoding = System.Text.Encoding.UTF8;
                        htmlCode = client.DownloadString(Functions.Links.GeraLinkCompleto(this, "/HtmlModule") + "?TextID=" + DR.TextID.ToString() + "&TypeTextID=" + ID.ToString());
                    }

                    texto = texto.Replace(match.ToString(), htmlCode);
                }

    Nesse código eu uso outra página para gerar o HTML e depois faço "download" desse html.

    Isso funcionou para módulos que não realizam postback.

    Este é meu primeiro post aqui, porém já sou usuário de fóruns (não de programação) há alguns anos já e sei o quanto é chato responder uma questão que já possui resposta.

    Utilizei a busca, mas não sei se não soube me expressar o que eu queria ou não existia mesmo. Por isso, caso haja resposta, me desculpem. 

    Muito Obrigado!

    []'s

    Fegabriel.

    terça-feira, 30 de setembro de 2014 15:07

Todas as Respostas

  • Olá Fegabriel,

     esse controle não poderia ser adicionado no evento "Page_Init" de sua página ? 

    quarta-feira, 1 de outubro de 2014 11:54
  • Oi, Daniel!

    Então, eu posso sobrecarregar o Page_Init dentro de um UserControl? Pq na verdade eu já estou dentro de um.

    Se sim, como? 

    Fui pesquisar sobre usar o Init do UserControl e em paralelo achei um link que me ajudou!

    http://www.tomot.de/en-us/article/3/asp.net/create-a-control-in-the-codebehind-and-retrieve-its-rendered-output

    Esse link me ajudou a montar o Bind e não precisei do gato que fiz acima, porém quando tenho um UserControl com um formulário e Validações ele me apresentou dois erros:

    Um falando que o TextBox devia estar dentro de um <form> com runat="server" (o que achei estranho, pois na minha master tem...), enfim, coloquei o form dentro do ascx do UserControl e ele me apresentou outro erro:

    RegisterForEventValidation can only be called during Render();

    Não faço ideia do que é isso... 

    O código ficou assim:

    string patternModule = @"\[(t|T)ype(t|T)ext(i|I)(d|D)=(\d*)\]";
                foreach (Match match in Regex.Matches(texto, patternModule, RegexOptions.IgnoreCase))
                {
                    Int32 ID = Int32.Parse(match.Groups[5].Value);
                    tb_TypeTexts menu = PageB.DBConnTypes.GetText(ID);


                    StringBuilder b = new StringBuilder();
                    HtmlTextWriter h = new HtmlTextWriter(new StringWriter(b));
                    UserControlBase controle = (UserControlBase) this.LoadControl(Paths.UserControls + menu.UserControlName);
                    controle.Text = DR;
                    controle.DataBind();
                    controle.RenderControl(h);
                    string controlAsString = b.ToString();

                    texto = texto.Replace(match.ToString(), controlAsString);
                }

    Obrigado.

    quarta-feira, 1 de outubro de 2014 14:29