Inquiridor
Incluir UserControl a partir de uma string

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.
Todas as Respostas
-
-
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.