Criando uma área colapsável no ASP.NET
-
19-09-2019 - |
Pergunta
Atualmente, construí um colapso-controlo que se comporta semelhante a um rótulo (AssociatedControlid) para controlar o estado de colapso de um controle.
Seguindo o controle, eu gostaria de construir:
colapsablearea http://img692.imageshack.us/img692/3307/stackoverflowcollapseab.jpg
Eu pensei em algo como:
Coloque minha construção já colapsableControl e algum outro controle (por exemplo, painel) para obter um colapsablearea.
primeira tentativa:
Tentei estender um painel e fiz o seguinte:
this.Parent.Controls.Add(collapsableControl);
Mas isso me deu: "Não correto etapa do ciclo de vida", "não posso modificar", "NullReference", ... exceções
Então, eu tentei (que acredito que a melhor escolha, devido a não obter Tagkey):
Eu estendi um espaço reservado e fiz o seguinte:
this.Controls.Add(collapsableControl);
this.Controls.Add(collapsablePanel);
Isso causou outros problemas, como: eu só quero definir o texto do painel, o estilo do painel, ...
Wired!
Você tem alguma solução para esse cenário?
editar:
Eu tive outra solução:
Outra solução http://img109.imageshack.us/img109/3307/stackoverflowcollapseab.jpg
"Colapsablearea" é do tipo "controle", contendo 2 propriedades privadas extras:
- "ColapsableControl"
- "Painel"
Eu pensei que seria suficiente, para redirecionar o getter do colapsablearea.Controls para colapsablearea.panel.controls. em colapsablearea.createchildControls () i Instancie e adiciono o colapsableControl e o painel à base.Controls e em colapsablearea.renderchildren () renderize esses 2
Meus problemas agora: o colapsableControl receberá um clientID (sem definir um ID) - o painel não renderizará o colapsableControl falhará (ou desmaiou), se o painel contiver <%> - tags
alguma sugestão?
editar:Corrigi o comportamento do ID ausente - basta definir o colapsableControl.associatedControlid para o painel.clientId ... mas - ao colocar < %> no painel, ele não será renderizado ?? !!
Solução 2
Oh, como é que - eu resolvi esse problema:
public sealed class CollapsableArea : Control
{
private const string ViewStateKeyCollapsableContentClientID = "collapsableContentClientID";
private string CollapsableContentClientID
{
get
{
var obj = this.ViewState[ViewStateKeyCollapsableContentClientID];
if (obj == null)
{
var collapsableContentClientID = Guid.NewGuid().ToString();
this.ViewState[ViewStateKeyCollapsableContentClientID] = collapsableContentClientID;
return collapsableContentClientID;
}
return (string)obj;
}
}
/// <summary>
/// Gets or sets the header text.
/// </summary>
/// <value>The header text.</value>
public string HeaderText
{
get
{
this.EnsureChildControls();
return this._collapseControl.Text;
}
set
{
this.EnsureChildControls();
this._collapseControl.Text = value;
}
}
public override ControlCollection Controls
{
get
{
// redirect controls
return this._collapsableContent.Controls;
}
}
#region child controls
private readonly Panel _collapsableContent = new Panel();
private readonly CollapsableControl _collapseControl = new CollapsableControl();
#endregion
public override Control FindControl(string id)
{
// need to redirect
if (string.Equals(id, this._collapsableContent.ID))
{
return this._collapsableContent;
}
return this._collapsableContent.FindControl(id);
}
protected override void CreateChildControls()
{
base.Controls.Clear();
var collapsableContentClientID = this.CollapsableContentClientID;
this._collapsableContent.ID = collapsableContentClientID;
this._collapseControl.AssociatedControlID = collapsableContentClientID;
base.Controls.Add(this._collapseControl);
base.Controls.Add(this._collapsableContent);
}
protected override void RenderChildren(HtmlTextWriter writer)
{
this._collapseControl.RenderControl(writer);
// hack for code blocks
if (!this.Controls.IsReadOnly)
{
this._collapsableContent.RenderControl(writer);
}
else
{
this._collapsableContent.RenderBeginTag(writer);
base.RenderChildren(writer);
this._collapsableContent.RenderEndTag(writer);
}
}
}
Outras dicas
Se você estiver atrás de um painel simples, em vez de reinventar a roda, poderá usar o controle do painel dobrável:
http://www.asp.net/ajax/ajaxcontroltoolkit/samples/collapsiblePanel/CollapsiblePanel.aspx
Pode ser a maneira mais fácil de obter a funcionalidade que você procura?
Seu controle deve obter uma propriedade de controle de modelo para definir conteúdo colapsável. E como você disse, uma propriedade AssociatedControlid que obtém o ID de controle do rótulo.
public class CollapsableArea : WebControl, INamingContainer
{
public string AssociatedControlID { get; set; }
public ITemplate ContentTemplate { get; set; }
}
Você precisa registrar um jQuery nos scripts de inicialização da página.
$("#The AssociatedControlID client control id").click(function(e) {
$("#The CollapsableArea client control id").toggle();
}