venerdì 12 agosto 2011

How To: Costum Control raise Events

Attenzione che questa è complessa.

Il mio scopo è quello di creare un controllo ( custom web control ) che contenga una Label, una TextBox e un Bottone, ora il necessario per l'esempio è una banalissima pagina Asp.Net che dovrà poi contenere il nostro controllo.

Nel mio caso la cosa non è poi così semplice, anzi questo è solo l'inizio.

Vi serve sicuramente comprendere a cosa serve quest' interfaccia IPostBackEventHandler anche onestamente che cosa avvenga "prima che si scateni il nostro evento" ha poco interesse.

using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Test
{
[ToolboxData("<{0}:TextField runat=server></{0}:TextField>")]
public class TextField : WebControl ,IPostBackEventHandler
{
public event EventHandler StartSearch;

private string _referencedTableName = "";

private string _DataCaption = "default";

private string _DataValue;

private string _CssClassError;

private string _CssClassMaster;

private string _TxtLenght ="100";

public string referencedTableName
{
get { return _referencedTableName; }
set { _referencedTableName = value; }
}

public string DataCaption
{
get { return _DataCaption; }
set { _DataCaption = value; }
}

public string DataValue
{
get { return _DataValue; }
set { _DataValue = value; }
}

public string CssClassError
{
get { return _CssClassError; }
set { _CssClassError = value; }
}

public string CssClassMaster
{
get { return _CssClassMaster; }
set { _CssClassMaster = value; }
}

public string TxtLenght
{
get { return _TxtLenght; }
set { _TxtLenght = value; }
}

public Label labelText = new Label();
public TextBox textbox = new TextBox();
public Button btnSearch = new Button();

protected override void CreateChildControls()
{

this.EnableViewState = true;

Panel pnl = new Panel();

pnl.CssClass = _CssClassMaster;
Controls.Add(pnl);

labelText.Text = _DataCaption;
labelText.CssClass = "formLabel";
pnl.Controls.Add(labelText);

textbox.CssClass = "formText";
pnl.Controls.Add(textbox);

if (_TxtLenght != "")
{
textbox.Width = new Unit(_TxtLenght+ "px");
}

Literal lsp = new Literal();
lsp.Text = "&nbsp;&nbsp;&nbsp;";
pnl.Controls.Add(textbox);


btnSearch.Text = "...";
pnl.Controls.Add(textbox);

btnSearch.ID = "btnSearch_for_" +
_DataCaption.Replace(" ", "_").ToString();

btnSearch.Attributes.Add("onclick",
Page.ClientScript.GetPostBackEventReference
(this,btnSearch.ID.ToString()));

btnSearch.Attributes.Add("name", btnSearch.ID);

pnl.Controls.Add(btnSearch);


Literal l = new Literal();
l.Text = "<br/>";

pnl.Controls.Add(l);

}

public void RaisePostBackEvent(string eventArgument)
{
if (StartSearch != null)
{
StartSearch(textbox.Text, new EventArgs());
}
}
}
}



il tutto si concentra nel punto:

pnl.Controls.Add(textbox);


btnSearch.ID = "btnSearch_for_" +
_DataCaption.Replace(" ", "_").ToString();

btnSearch.Attributes.Add("onclick",
Page.ClientScript.GetPostBackEventReference
(this,btnSearch.ID.ToString()));

btnSearch.Attributes.Add("name", btnSearch.ID);

pnl.Controls.Add(btnSearch);


Momento in cui definiamo il controllo.

E qui

public void RaisePostBackEvent(string eventArgument)

{
if (StartSearch != null)
{
StartSearch(textbox.Text, new EventArgs());
}
}


Momento i cui definiamo l'evento.

Senza l'interfaccia l'evento non viene ne registrato ne gestito.

Per completare l'oggetto viserve :

Implemetare l'interfaccia IPostBackDataHandler

public virtual bool LoadPostData(string postDataKey, 

System.Collections.Specialized.NameValueCollection postCollection)
{
String presentValue = Text;
String postedValue = postCollection[postDataKey];

if (presentValue == null || !presentValue.Equals(postedValue))
{
Text = postedValue;
return true;
}

return false;
}


public void RaisePostDataChangedEvent()
{
if (TextChanged != null)
{
TextChanged(this, new EventArgs());
}
}


La proprietà che contiene il testo :

public String Text

{
get
{
return (String)ViewState["Text"];
}

set
{
ViewState["Text"] = value;
}
}


Ricordandovi di scrivere la EnabledViewState = true durante la creazione dei controlli.

E il gioco è fatto !

1 commento:

Anonimo ha detto...

il solito anonimo, con il solito ..." davvero ottimo post " ??
No! ho seguito l'esempio, l'ho provato e va, ma hai provato a pubblicare questo controllo in un altro costum control ?