[Asp.net] Editable Treeview II

Siguiendo con el anterior artículo de personalizar un TreeView I   para poder editar los nodos hoy veremos precisamente la parte donde habilitamos la edición de los nodos.


Crearemos una nueva clase que llamaremos TreeNodeEdit que heredara de TreeNode. Con esto ya tendremos la base para montar nuestro nodo editable.


[ToolboxData(«<{0}:TreeNodeEdit runat=server></{0}:TreeNodeEdit>»)]
public class TreeNodeEdit : TreeNode

Crearemos las propiedades públicas para poder configurar nuestro Nodo.



  • bool Editable –>Para hablilitar la edición del nodo.

  • string TextBoxValue –> Valor de la edición.

  • string OldValue –> Valor anterior a la edición.

  • string EditImageUrl –> Url del a imagen del botón editar.

  • string CancelImageUrl –> Url de la imagen del botón cancalar.

  • string SaveImageUrl –> Url de la imagen del botón guardar.

  • string EditTooltip –> Tooltip del botón editar.

  • string SaveTooltip –> Tooltip del botón guardar.

  • string CancelTooltip –> Tooltip del botón cancelar.

  • string TextBoxValueCSSView –> estilo del textbox de la edición.

Ejemplo:

[Localizable(true), Category(«Edit»)]
public string CancelImageUrl
{
get{
if (ViewState[«CancelImageUrl»] != null)
return ViewState[«CancelImageUrl»].ToString();
else
return «»;
}
set{
ViewState[«CancelImageUrl»] = value;
}
}

Ahora veremos realmente donde se encuentra la chica del control y eso es en el evento RenderPostText que es que se lanza justo después de pintar el nodo y nos servirá para pintar los controles de edición justo cuando termina el nodo.

protected override void RenderPostText(HtmlTextWriter writer)

if (Editable)
{
#region Variables

this.SelectAction = TreeNodeSelectAction.Select;
string idEdit = Guid.NewGuid().ToString();
string idView = Guid.NewGuid().ToString();
string idTb = Guid.NewGuid().ToString();
Page page = HttpContext.Current.CurrentHandler as Page;

#endregion Variables

#region script

if (page == null)
throw new NotSupportedException(«Error»);

#endregion script


Primero comprobamos si el nodo está habilitado para ser editado y luego inicializamos los identificadores que posteriormente necesitaremos para localizar los controles que utilizaremos para la edición del nodo.


Otra parte importante del código es que como no podemos acceder directamente a la página desde un nodo del TreeView, la tenemos que recuperar del contexto actual.




  • Panel Modo Vista: crearemos un panel que contendrá los controles que mostrarán los datos en modo vista, una label para mostrar los datos, la imagen para habilitar la edición la cual si no se informa utilizaremos una que tenemos guardada en los recursos del ensamblado y finalmente le añadiremos el evento onclick de cliente para lanzar la edición desde javascript (editNode).


#region Panel modo Vista

writer.AddAttribute(«id», idView);
writer.AddStyleAttribute(HtmlTextWriterStyle.Display, «inline»);
writer.RenderBeginTag(HtmlTextWriterTag.Div);

Label lb = new Label();
lb.CssClass = this.TextBoxValueCSSView;
lb.Text = string.Format(«({0})», TextBoxValue);
lb.RenderControl(writer);

writer.Write(» «);

Image imgV = new Image();
if (!string.IsNullOrEmpty(EditImageUrl))
imgV.ImageUrl = EditImageUrl;
else
imgV.ImageUrl = page.ClientScript.GetWebResourceUrl(this.GetType(), «TreeviewEditControl.Resources.ItemEdit.gif»);
imgV.Attributes.Add(«onclick», «editNode( ‘» + idEdit + «‘, ‘» + idView + «‘)»);
imgV.Style.Add(HtmlTextWriterStyle.Cursor, «Pointer»);
imgV.ImageAlign = ImageAlign.Middle;
imgV.ToolTip = this.EditTooltip;
imgV.RenderControl(writer);

writer.Write(» «);

writer.RenderEndTag();

#endregion Panel modo Vista




  • Panel Modo Edición: crearemos otro panel para mostrar los controles cuando el nodo esté en edición. Un textBox para insertar los datos y dos imageButtons. Una para guardar los datos y otra para anular la edición. Igual que anteriormente le añadiremos el evento onclick para las acciones desde javascript ( viewNode, cancelNode).

 


writer.AddStyleAttribute(HtmlTextWriterStyle.Display, «none»);
writer.AddAttribute(«id», idEdit);
writer.RenderBeginTag(HtmlTextWriterTag.Div);

TextBox tb = new TextBox();
tb.Text = TextBoxValue;
tb.ID = idTb;
tb.Width = Unit.Pixel(40);
tb.RenderControl(writer);

writer.Write(» «);

ImageButton imgE = new ImageButton();
if (!string.IsNullOrEmpty(SaveImageUrl))
imgE.ImageUrl = SaveImageUrl;
else
imgE.ImageUrl = page.ClientScript.GetWebResourceUrl(this.GetType(), «TreeviewEditControl.Resources.disk_blue.gif»);

imgE.OnClientClick = «viewNode(‘» + _owner.ClientID + «‘, ‘» + idTb + «‘,’EditNode|» + this.ValuePath + «‘)»;
imgE.ImageAlign = ImageAlign.Middle;
imgE.ToolTip = this.SaveTooltip;
imgE.RenderControl(writer);

writer.Write(» «);

//Imagen para cancelar
Image imgC = new Image();
if (!string.IsNullOrEmpty(CancelImageUrl))
imgC.ImageUrl = CancelImageUrl;
else …


Otra de las cosas que tenemos que tener muy encuenta es guardar correctamente el viewState del control. Para eso las propiedades públicas las vamos guardando en una variable privada que es un StateBag ( guarda el stado de vista de los controles Asp.net ).


Luego cuando el control guarda el viewState utilizaremos la clase Pair para guardar el estado de las propiedades base del control y las nuevas propiedades que nosotros hemos generado. Y al recuperar el estado actuamos a la inversa para que de esta manera se mantenga es estado completo del control.


StateBag _viewState;

private StateBag ViewState
{
get{
if (this._viewState == null)
{
this._viewState = new StateBag();
if (!((IStateManager)this._viewState).IsTrackingViewState)
((IStateManager)this._viewState).TrackViewState();
}
return this._viewState;
}
}

protected override object SaveViewState()
{
Pair state = new Pair();
state.First = base.SaveViewState();
if (this._viewState != null)
state.Second = ((IStateManager)this._viewState).SaveViewState();
return state;
}

protected override void LoadViewState(object state)
{
if (state == null)
base.LoadViewState(state);
else
{
Pair p = (Pair)state;
base.LoadViewState(p.First);
((IStateManager)this.ViewState).LoadViewState(p.Second);
}
}


Para finalizar con la generación de este control solo nos faltaría destacar los recursos embebidos como las imágenes y el fichero Javascript


[assembly: System.Web.UI.WebResource(«TreeviewEditControl.Resources.disk_blue.gif», «img/gif»)]
[assembly: System.Web.UI.WebResource(«TreeviewEditControl.Resources.disk_blue_error.gif», «img/gif»)]
[assembly: System.Web.UI.WebResource(«TreeviewEditControl.Resources.ItemEdit.gif», «img/gif»)]
namespace TreeviewEditControl

La función más importante del fichero javascript es la que genera el postback al servidor y envía el identificador del control y una array de argumentos que utilizaremos para recuperar los datos del nodo editado.


function viewNode( control, txtID, args )
{
var txt = document.getElementById( txtID );
if( txt != null)
__doPostBack( control, args + «|» + txt.value );

}


Una vez finalizado el control lo utilizaremos en una página web y podemos recuperar los datos con el evento que creamos en el TreeView.


protected void TreeViewEdit1_TreeNodeEdit(object sender, TreeNodeEditEventArgs e)
{
//Guardar Datos
bool check = e.Checked;
string Nombre = e.NodoText;
string ID = e.NodoValue;
string valorInicial = e.OldValue;
string nuevoValor = e.NewValue;
}

 


Bueno yo creo que ya ha quedado claro como se ha creado el control, si tenéis dudas y queréis probar el código os lo dejo para que os lo podáis bajar.


 


Cross-Posting desde http://lonetcamp.com


 


 

[Asp.net] Editable Treeview I

En más de una ocasión nos ha sido de mucha utilidad un control del tipo TreeView para mostrar una jerarquía de datos, pero el control se nos puede quedar un poco limitado cuando pretendemos interactuar con los datos.


Por ese motivo he creado un control TreeView con nodos editables, y el resultado final es como este:


 


Comenzaremos creando un proyecto de librerías de clase para albergar nuestro control, a la clase le llamaremos TreeViewEdit y heredaremos de System.Web.UI.WebControls.TreeView.

[ToolboxData(«<{0}:TreeViewEdit runat=server></{0}:TreeViewEdit>»)]
public class TreeViewEdit : TreeView

Realmente toda la potencia del control no se encuentra en el TreeView, sino en los Nodos que le daremos la posibilidad de ser editados. En esta clase lo único que tenemos que hacer es un nuevo evento para capturar la información modificada del nodo.


Para eso crearemos un nuevo evento llamado TreeNodeEdit.

[Category(«Data»)]
public event TreeNodeEditEventHandler TreeNodeEdit;
protected virtual void OnTreeNodeEdit(TreeNodeEditEventArgs e)
{
if (TreeNodeEdit != null)
{
TreeNodeEdit(this, e);
}
}

Si os fijáis nuestro evento se basa en un delegado personalizado TreeNodeEditEventHandler y TreeNodeEditEventArgs para customizar el conjunto de argumentos que utilizaremos para devolver los datos del nodo modificado.


El delegado:

public delegate void TreeNodeEditEventHandler(object sender, TreeNodeEditEventArgs e);

La clase que utilizaremos para nuestros argumentos:

public class TreeNodeEditEventArgs : System.EventArgs
{
#region Variables

private string _nodoText;
private string _nodoValue;
private string _oldValue;
private string _newValue;
private bool _checked;

#endregion Variables

#region Propiedades

public string NodoText { get { return _nodoText; } }
public string NodoValue { get { return _nodoValue; } }
public string OldValue { get { return _oldValue; } }
public string NewValue { get { return _newValue; } }
public bool Checked { get { return _checked; } }

#endregion Propiedades

#region Constructor

public TreeNodeEditEventArgs(string nodotext, string nodoValue,
string oldValue, string newValue, bool check)
{
this._nodoText = nodotext;
this._nodoValue = nodoValue;
this._oldValue = oldValue;
this._newValue = newValue;
this._checked = check;
}

#endregion Constructor
}


Gracias a esta clase cuando consumamos el evento del TreeView podremos recuperar los datos:

  bool Check = e.Checked;
string Nombre = e.NodoText;
string ID = e.NodoValue;
string valorInicial = e.OldValue;
string NuevoValor = e.NewValue;

Finalmente para tener finalizada la primera parte del control tan solo nos queda sobrescribir dos eventos:




  • RaisePostBackEvent para procesar los eventos procesados por el control al enviar los datos al servidor.
protected override void RaisePostBackEvent(string eventArgument)
{
base.RaisePostBackEvent(eventArgument);

string[] args = eventArgument.Split(‘|’);
if (args.Length > 0)
{
if (args[0] == «EditNode»)
{
TreeNodeEdit node = (TreeNodeEdit)this.FindNode(args[1].ToString());

TreeNodeEditEventArgs arg = new TreeNodeEditEventArgs(node.Text,
node.Value,
node.OldValue,
args[2].ToString(),
node.Checked);

//Guardamos la modificación en el estado del control y lanzamos el evento correcto
node.TextBoxValue = args[2].ToString();
OnTreeNodeEdit(arg);
}
}
}


Esperamos una colección de argumentos separado por el caracter ‘|’ que envía el cliente al lanzar el postback.




  1. Comprobamos que los argumentos que esperamos son realmente de edición (args[0] == «EditNode»)


  2. El segundo argumento es el Path del nodo que hemos editado.


  3. Creamos un TreeNodeEditEventArgs con los datos recuperados del nodo.


  4. Invocamos el evento TreeNodeEdit a través del método OnTreeNodeEdit, con el argumento correctamente rellenado para que quien consuma nuestro evento pueda interactuar con los datos modificados.


  • OnPreRender para registrar el fichero Javascript que utilizaremos como recurso incrustado y darle una funcionalidad más ligera al interactuar con el cliente.
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.Page.ClientScript.RegisterClientScriptResource(GetType(), «TreeviewEditControl.Resources.JS.js»);
}

Me parece que para ser la primera parte es suficiente, en el próximo artículo entraremos a fondo con la clase TreeNodeEdit que es la clase que representan los nodos del TreeView.


Cross-Posting desde http://lonetcamp.com


 


 

Extender una propiedad de un ServerControl

Hoy una consulta en el foro MSDN me ha parecido muy interesante y por ese motivo y porque la explicación es un poco larga, describiré más detalladamente como poder hacer lo que Roberto Corona necesita.

http://forums.microsoft.com/MSDN-ES/ShowPost.aspx?PostID=3843776&SiteID=11

 En resumen Roberto está creando un control de servidor del cual pretende que una propiedad muestre los botones que se encuentren en el formulario para poderlo seleccionar, al etilo de un validador.

 

Para hacer esto crearé un proyecto web para probar el control y otro proyecto que será el propio control de servidor. La clase del control la llamaré ServerControl1.cs, ya lo sé, muy poco original !! 

El control es realmente sencillo:

Nuestro control heredará de WebControl y crearemos la propiedad ControlID para guardar el identificador del botón que queremos controlar 


[DefaultProperty("Text")] [ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")] public class ServerControl1 : WebControl { [DefaultValue(""), TypeConverter(typeof(ButtonConverter))] public string ControlID { get { object o = ViewState["ControlID"]; if (o == null) return String.Empty; return (string)o; } set { if (ControlID != value) ViewState["ControlID"] = value; } } protected override void RenderContents(HtmlTextWriter output) { if(String.IsNullOrEmpty(ControlID)) output.Write("Tienes que seleccionar un Botón"); else output.Write(ControlID); } }

Lo destacable de este código es la clase ButtonConverter, que es la que se encargará de devolvernos los controles button del formulario para poderlo elegir desde el control, esta clase esta basada en la clase ControlIDConverter.

http://msdn.microsoft.com/es-es/library/system.web.ui.webcontrols.controlidconverter(VS.80).aspx 

La clase ControlIDConverter se deriva de la clase StringConverter y proporciona una lista de id. de control para su presentación en un control de cuadrícula de propiedades en entornos en tiempo de diseño. La clase ControlIDConverter también actúa como clase base para las clases AssociatedControlConverter y ValidatedControlConverter, que son los convertidores de tipos para los controles Web y los controles que admiten atributos de propiedades de validación, respectivamente.


class ButtonConverter : StringConverter

 


protected virtual bool FilterControl(Control control) private string[] GetControls(IDesignerHost host, object instance) { IContainer container = host.Container; IComponent component = instance as IComponent; if ((component != null) && (component.Site != null)) { container = component.Site.Container; } if (container == null) { return null; } ComponentCollection components = container.Components; ArrayList list = new ArrayList(); foreach (IComponent component2 in components) { Control control = component2 as Control; if(control.GetType().Name == typeof(Button).Name) { list.Add(control.ID); } } list.Sort(Comparer.Default); return (string[])list.ToArray(typeof(string)); } public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) public override bool GetStandardValuesSupported(ITypeDescriptorContext context)

 

 El método a destacar es GetControl que es el que recupera la lista de IDs de los botones y el efecto final es exactamente como el de ControlToValidate de los validadores de Asp.NET.

 

 Ahora ya tenemos nuestra propiedad extendida para utilizar nuestro control de la manera que más nos guste.

Cross-Posting de http://lonetcamp.com

 

Y ya van dos Errores graves de Chrome !!!

Desde ayer que me están bombardeando con el nuevo navegador de Google, lo has probado? lo has probado?.


Pues para demostrar que no todo en la programación no es ni blanco ni negro, aqui tenéis el primer agujero de seguridad y además es un fallo garrafal por dejadez.


Este nuevo e innovador navegador está basado en Webkit de Apple, pero no se han molestado ni en implementar el parche que el mismo Apple publico para resolver este problema de seguridad.


Y ya van dos…..

http://es.wikipedia.org/wiki/WebKit

Suerte que es una versión Beta. 😉


Nos vemos.


 

Asp.net PoPup sin JavaScript !!!

En ASP siempre que hemos querido abrir una nueva ventana desde un botón, imageButton, etc. Hemos tenido que echar mano de JavaScript para poder abrir un nuevo navegador.

Pero hay un truco que podemos utilizar directamente desde asp.net y que gracias a la propiedad Target del formulario podemos definir como queremos que se muestre la página web.


protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) this.Form.Target = "_blank"; }

 

 Para hacer la prueba hemos definido la propiedad Target del formulario como _blank  y cada vez que recargemos la página lo hará en una nueva ventana. Si le damos un par de vueltas a esta propiedad le podemos sacar mucho partido.

Otra manera de hacer lo mismo pero que solo afecte por ejemplo cuando hacemos click en un botón y no siempre que recargamos la página sería. 


protected void Page_Load(object sender, EventArgs e) { Button1.OnClientClick = "form1.target='_blank'"; Button1.PostBackUrl = "Ventana.aspx"; }

 Cuando carga la página definimos en la propiedad OnClientClick «define el evento click en el cliente antes de enviar la petición al servidor» que el formulario abrirá una nueva ventana y en la propiedad PostBackUrl  definimos a que dirección se redirigirá después de hacer el recarga la página.

 Teniendo todo esto en cuenta porque no creamos un método en nuestra clase base para poder decidir si nuestros controles de servidor actúen de forma normal o abran una página nueva.

Para hacer esto posible crearemos un método genérico con tres parámetros.

  1. control: el control a personalizar.
  2. url: la dirección a donde redirigiremos.
  3. target: Una enumeración con las diferentes opciones que acepta la propiedad Target. 

private void DestinoLink<T>( ref T control, string url, Target target ) { switch (control.GetType().Name) { case "Button": case "LinkButton": case "ImageButton": control.GetType().GetProperty("OnClientClick").SetValue(control, this.form1.Name + ".target='_blank'", null); control.GetType().GetProperty("PostBackUrl").SetValue(control, url, null); break; case "HyperLink": control.GetType().GetProperty("Target").SetValue(control, this.form1.Name + ".target='_blank'", null); control.GetType().GetProperty("NavigateUrl").SetValue(control, url, null); break; } } /// <summary> /// Con el uso de Target indicamos al enlace donde tiene que abrirse. /// </summary> enum Target { _blank, _top, _self, _parent }

 

 Gracias a los genéricos informamos del tipo del control a personalizar y dependiendo del tipo que detectemos utilizaremos reflexion para definir sus propiedades. De esta manera independientemente de que el control sea un botón o un link podemos utilizar el método de la misma manera.

Para probar el código he creado dos páginas; una con un button, un linkButton y un hyperlink llamada «default.aspx» y otra con un texto llamada «ventana.aspx».


protected void Page_Load(object sender, EventArgs e) { DestinoLink<Button>(ref Button1, "Ventana.aspx", Target._blank); DestinoLink<HyperLink>(ref HyperLink1, "Ventana.aspx", Target._blank); DestinoLink<LinkButton>(ref LinkButton1, "Ventana.aspx", Target._blank); }

 De esta manera tan sencilla podemos preparar los controles de servidor para que habran una nueva ventana.

  

Espero que esta entrada os haya parecido interesante.

Nos vemos.

Cross-posting de http://lonetcamp.com

 

[Tip] Posicion Relativa – Absoluta en VS

Hoy me he encontrado con una pregunta que me parece muy interesante en el foro de MSDN.


Como poder definir en nuestro Visual Studio poder trabajar siempre con nuestros formularios ASP.NET de forma relativa y no de forma absoluta.


 http://forums.microsoft.com/MSDN-ES/ShowPost.aspx?PostID=3660415&SiteID=11


 La solución es muy sencilla Herramientas –> Opciones –> Diseñador HTML –> Posición CSS –> Opciones de Posición


De esta manera podemos definir si nuestros controles dentro del formulario HTML se alinearán de forma Absoluta  o de forma relativa de forma predeterminada.



Saludos

Aprender de la Experiencia

Después de la visita fugaz de Hadi Hariri, se nos ha quedado un gustillo agridulce.


Dulce por la excepcional experiencia de poder asistir a unas fenomenales ponencias de Hadi, que desde el primer momento se metió a la gente en el bolsillo y nos demostró lo gran experto que es y las tablas que tiene delante del público, a pesar que no le guste que se lo digan!!.


Agrio por lo corto de las sesiones, somos conscientes que estas oportunidades se tienen que aprovechar al 100% y en esta ocasión se nos ha hecho muy corto, pero de estas experiencias se tiene que aprender todo, hasta de no repetir los fallos y dar más tiempo a los ponentes para poder efectuar sus charlas.


Espero que a todos os haya parecido una gran experiencia como me lo pareció a mí.


Nos vemos en la próxima.



 


Más fotos en : http://lonetcamp.com/Community/media/g/wcf08/default.aspx


Cross-Posting desde http://lonetcamp.com


 

LoNetCamp con Hadi Hariri

Todo aquel que el Sábado 19 de Julio  esté por Tarragona pase cerca o esté de vacaciones, está invitado al nuevo evento de LoNetCamp.


         Aplicaciones distribuidas con WCF


El modelo de programación orientado a servicios de Windows Communication Foundation se basa en Microsoft .NET Framework y simplifica el desarrollo de sistemas interconectados. WCF unifica una gran variedad de funcionalidades de sistemas distribuidos en una arquitectura organizable y extensible.


         Mejorando la experiencia Web con ASP.NET AJAX


Mediante componentes del lado del cliente y del servidor, ASP.NET AJAX permite al desarrollador crear páginas web en ASP.NET 2.0 que pueden actualizar datos en la página web sin un recarga completa de la misma. Dotando a nuestras aplicaciones web una experiencia de usuario rica igual a las tradicionales aplicaciones Windows.


         Metodologías y Pruebas Unitarias


Es posible mejorar nuestro Código sin renunciar a la productividad ?


Ponentes:


Hadi Hariri – Microsoft  MVP
Ponente habitual en conferencias internacionales sobre temas relacionados con la tecnología .NET,  ha escrito numerosas publicaciones.  Apasionado de la arquitectura de software y el desarrollo de aplicaciones web, vive en Málaga y es el fundador del grupo de usuarios .NET de la ciudad.


Marc Rubiño
Director del departamento web de ACI GRUP S.L. Microsoft MCAD con amplia experiencia en desarrollo en la plataforma .NET y el desarrollo de proyectos web. Colaborador habitual de los foros de MSDN y coordinador del grupo de Usuarios de Tarragona.


Agenda:


09:00   WCF


10:15   ASP.NET AJAX


11:30   Coffee Break


11:45   Metodologías


13:00   Preguntas y Despedida


 


Orfeó Reusenc


C/  Sant Lloreç, 14


43201 Reus (Tarragona)


 


Registro Gratuito aforo limitado:  http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032382200&Culture=es-ES


 

Colaboradores:


   


  

ASP.NET AJAX Async Page_Load

Ya es por todos sobradamente conocido los grandes beneficios que nos aporta ASP.NET AJAX a nuestras aplicaciones web. Pero no solo de Postbacks vive el hombre, que pasa si yo no solo quiero recargar partes de mi página web en un postback, sino cargar la primera vez las partes de la página asincronamente?


Pues de eso precisamente pretendo hablar hoy, imaginaros la típica web con diferentes apartados y que es muy posible que más de un apartado hagan que nuestra página tarde mucho en cargar, siempre tendremos la posibilidad de mostrar una barra de progreso en nuestra web, pero porque no utilizar la potencia de ASP.NET Ajax para cargar independientemente cada parte y que el resto de nuestra página se cargue con normalidad.


Para demostrar esto he creado una página web dividida en dos partes:





  1. Nuestro ScritManager para que nuestra aplicación ASP.NET AJAX funcione.


  2. Un UpdatePanel con un DataList en su interior que será nuestra parte asincrona.


  3. Una Label y un botón que actualizará nuestro updataPanel de la forma clásica.

El funcionamiento del ejemplo es muy simple, la página carga el texto de la label y el botón. Al mismo tiempo carga los datos de la lista asincronamente mostrando una progressbar.


No he querido complicar demasiado el ejemplo y recuperaremos los datos desde el cliente mediante los Pagemethods.




  1. Activamos los PageMethods: <asp:ScriptManager ID=»ScriptManager1″ runat=»server» EnablePageMethods=»True»>


  2. Creamos un método público y estático y utilizamos el atributo WebMethod para que sea accesible desde el cliente como si fuera un webservice. Luego le definimos que los datos se tienen que serializar de forma compatible con Json con ResponseFormat.


  3. Para simular mejor esta situación he añadido un sleep Threading que retrasa la carga 10 segundos.


Para hacer posible la idea tenemos que utilizar código en el cliente que se encargue de cargar la lista asincronamente y no influya en el resto de la página.






  • La primera función Actualizar es la encargada de llamar a nuestro método del servidor y enlazarla con el evento load de la página para que nuestra idea surja efecto y se cargue la lista la primera vez.


  • La función actualizarOK es la encargada de pintar los datos si todo ha ido correcto.


  • La función actualizarFAIL es la encargada de tratar los posibles errores.

El ejemplo funcionando.



El texto de la página y el botón se han cargado perfectamente mientras que la lista se está cargando…



Una vez finalizada la carga se muestran los datos correctamente. Y si forzamos un postback con el botón y actualizamos el updatepanel ya no se lanzará nuestro código de precarga.


 


Bueno espero que esta propuesta os haya parecido interesante, os dejo el proyecto para que podáis jugar con el y espero que lo podáis utilizar en vuestros proyectos ;-).


Happy Coding 


  Async Page_Load


Cross-Posting de www.lonetCamp.com


 

Error al instalar SQL Express en un windows XP SP2

Bueno como no me quiero enrollar y de lo que se trata es de solucionar un problema este es el error: 


WMI Error 2147749907(0x80041013).


Este error me surgió al intentar abrir una base de datos Access y posteriormente  intentar instalar un SQL Express en un Windows XP con SP3 y el Framework 2.0 con el SP1.


 Después de intentar muchisimas sugerencias:


http://blogs.msdn.com/jpapiez/archive/2004/12/09/279041.aspx


http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=193534&SiteID=1


La respuesta para mi problema era mucho más sencillo que todo eso:


 



 


Instalar el Proveedor SNMP WMI. de los componentes de windows.


Con eso la conexión y la instalación del SQL Express funcionó a la primera.


Bueno espero que todo el tiempo que he tenido que perder para poder encontrar esta chorrada de solución sea útil para alguien.


Saludos.


Cross-posting de www.lonetcamp.com