miércoles, 23 de septiembre de 2009

Ajax .Net: ModalPopup y el control DropDownList.

¿Por qué al escoger un item de un DropDownList que está en un ModalPopupExtender, del lado del servidor siempre me devuelve el index del primer item?

Solución: Esto me estaba ocurriendo porque en el evento Page_Load existe un código para llenar el DropDownList, entonces cada vez que se escogía un item y se daba clic en el botón "Guardar" que esta también en el ModalPopup, sucedía que el ciclo de vida de la página pasaba otra vez por el evento Page_Load (lo cual es obvio) y por eso en otro método que tenía, siempre iba a recoger el mismo valor. La solución fue poner una variable de Sessión antes de que el DropDownList se vuelva a llenar.

martes, 15 de septiembre de 2009

Asp.Net: Recuperar ID de fila en GridView a partir de DataKeys

Recuperar el ID de una fila en GridView a partir de la propiedad DataKeys:

key = Convert.ToString(this.grid.DataKeys[this.grid.SelectedIndex].Value);

En la variable key queda un valor que representa el ID del registro. En el GridView se tuvo que haber definido mínimo un valor para la propiedad DataKeyNames. En caso de haber definido más de un DataKeyName, para poder recuperarlo sería de la siguiente forma:

key = Ctype(grid.DataKeys(gris.SelectedIndex).Item(1)

La propiedad Item(1) escoge el segundo Código de la colección DataKeyNames suponiendo que tenemos una clave primaria formada con dos campos.

La ventaja de esto es que podemos poner un columna oculta pero en el DataSource del GridView existe un Select que está recuperando esos valores de las columnas.

Ajax.Net: Más problemas con controles Ajax.Net

1º Tengo un ModalPopupExtender, el problema es que al hacer clic a un botón que está dentro del ModalPopup, éste hace que el modal desaparezca.

Eso ocurre, porque cualquier botón, textbox, etc, que haga Postback, ya sea porque tiene la propiedad AutoPostBack en True o porque se lanza el evento PostBack desde código Javascript, tendremos como resultado que el ModalPopup termine su función. El control ModalPopup está programado para que se cierre cuando ocurra un PostBack dentro de éste.

Solución: La solución es usar Web Services. De hecho esta es la forma que se debería utilizar para actualizar controles dentro de un ModalPopup. Además hay que usar un evento de control HTML para que del lado del servidor llame al WebService. Generalmente se usa el evento onblur el cual equivale a TextChanged de un TextBox, suponiendo que el caso es un TextBox, para otros controles se podría usar el evento onchange.

2º No funcionan los validadores en un ModalPopup.

Solución: Tanto los validadores como los controles que validan deben estar dentro de un ValidationGroup.

3º Mostrar ModalPopup programáticamente.

Exite un problema con éste control ya que la propiedad TargetControlID no puede estar vacía. El truco está en asignarle un control HTML del tipo Hidden y que tenga la propiedad runat="server". Luego, con ayuda de otro botón, se puede poner en code behind el código para mostrar al ModalPopup.

Ejemplo:
ModalPopupExtender1.Show()

La ventaja es que si estamos creando un modal con cuadros de texto dentro, éstos se pueden inicializar con el valor que queramos antes de que el modal aparezca.

Ajax: Recuperar el ID de un control Web Server

En ocasiones hay que recuperar el ID de un control en Ajax.Net. en el código Javascript. Podemos usar el objeto getElementById, el objeto $get, $find, pero que ocurre si el objeto está en un ContentPlaceHolder. Si esto ocurre, el control en la página web toma un nombre de ID diferente; el nombre se complementa y para poner un ejemplo podría ser éste: ctl00_ContentPlaceHolder1_Button1

Para recuperar el ID exacto y poder usarlo correctamente, se puede usar la instrucción:
<%= expresion %>, donde expresion se cambia por el nombre del control que le asignamos del lado del servidor seguido de la propiedad ControlID.

function fnTxt() {
var obj = $get('<%= TextBox1.ClientID %>');
...
}

Ajax: Lanzar un PostBack

Ejemplo para ejecutar un evento postback desde javascript usando el Ajax Framework:

function postbackFromJS(sender, e) {
var postBack = new Sys.WebForms.PostBackAction();
postBack.set_target(sender);   
postBack.set_eventArgument(e);
postBack.performAction();
}

CSS: Comprimir archivos CSS rápidamente en Visual Studio

Es relativamente sencillo, solo hay que descargar el ejecutable "YUI Compressor". Descomprimimos el archivo en un directorio que preferiblemente debemos crear. Luego vamos a Visual Studio y en: Herramientas -> Herramientas Externas ponemos:

Título: YUI Compression
Comando: C:\WINDOWS\system32\java.exe
Argumentos: -jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemPath) –v

Argumentos para comprimir CSS con copia sin tener que reemplazar el original:

-jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemDir)$(ItemFileName).min$(ItemExt) –v


Argumentos para comprimir JS:

-jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemPath) –v --charset utf-8

Argumentos para comprimir JS con copia sin reemplazar el original:

-jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemDir)$(ItemFileName).min$(ItemExt) –v --charset utf-8

Nota: Después de comprimir un archivo CSS sería bueno quitar el punto y coma que siempre se pone al final de cada regla de las clases o selectores. El punto y coma en la última regla es opcional. Para quitarlo rápidamente ese punto y coma, simplemente hay que hacer un "Replace" de la siguiente combinación de caracteres:

;) (punto y coma con paréntesis)

Luego aceptamos el cuadro de diálogo y listo. Para hacer la prueba, abrimos un archivo CSS en Visual Studio, y luego vamos a Herramientas -> YUI Compression. El resultado será que todas las reglas de CSS se comprimen al máximo; es decir, desaparecen espacios, cambios de línea innecesarios y todo al final queda en una sola línea o más líneas dependiendo de la cantidad de CSS que tenga el archivo. Pero definitivamente lo comprime.

Está de sobra decir, pero para los novatines, les comento que hay que tener java instalado.

Por cierto, ¿saben cómo restaurar el código CSS a su estado original? Yo si sé, jaja!, solo hay que presionar la siguiente combinación de teclas: Ctrl + K + D. Dependiendo de los settings que tengan su Visual Studio, esa combinación de teclas puede ser diferente, por eso, en caso de que no funcione verifiquen en el menú Editar -> Opciones Avanzadas.

Y para mayor detalle una demostración de tantas que existen en YouTube:


También está éste link: Ver

Yui compressor online:Ver

domingo, 13 de septiembre de 2009

GridView: Eliminar múltiples registros.

Referencias:

csharpdotnetfreak.blogspot.com

GridView: Problemas con el GridView?

¿No aparece el paging?
Puede ser porque el PageSize tiene un valor superior para el GridView. Revisar la propiedad PageSize en el cuadro de propiedades.

¿No hace Paging cuando cambia valor en el DropDownList que se coloca en el PagingTemplate?
Activar la propiedad AutoPostBack del DropDownList.

¿El PageTemplate desaparece cuando PageSize es mayor que la cantidad de registros real que se pueden imprimir en el GridView?
En el evento DataBound del GridView poner lo siguiente:
grid.BottomPagerRow.Visible = True

¿La fila a la que se le hizo clic en un GridView, no queda seleccionada?
Puede ser por varias cosas:
1º Se está usando themes pero no se indicó en la directiva Page o en el archivo de configuración.

2º Si no se está usando Themes, entonces puede ser porque la hoja de estilos no se asoció al archivo o porque no se configuró la propiedad SelectedRowStyle del GridView.

3º La fila no tiene el evento onclick y por eso no ocurre el postback.

4º Puede ser que tenga el evento onclick pero el atributo EnableEventValidation está en true (predeterminado) y debería estar en False.

¿Un PageMethod asociado con el Grid no se ejecuta?
La propiedad EnablePageMethods del ScripManager está en False y debería ser True.

viernes, 4 de septiembre de 2009

Asp.Net: Limpiar por completo el VIEWSTATE

Para poder limpiar el viewstate por completo hay que sobre escribir el método SavePageStateToPersistenceMedium y el método LoadPageStateFromPersistenceMedium.

En C# se puede hacer de esta forma:

protected override object LoadPageStateFromPersistenceMedium()
{
return Session["ViewState"];
}

protected override void SavePageStateToPersistenceMedium(object viewState)
{
Session[
"ViewState"] = viewState;
RegisterHiddenField("__VIEWSTATE", "");
}

En Visual Basic .Net:

Protected Overloads Overrides Sub SavePageStateToPersistenceMedium(ByVal viewState As Object)
Page.ClientScript.RegisterHiddenField("__VIEWSTATE", "")
End Sub

Protected Overloads Overrides Function LoadPageStateFromPersistenceMedium() As Object
Return Session("ViewState")
End Function


Referencias:
www.carloszanini.com.ar

www.tek-tips.com

www.listhosting.net

Todo sobre ViewState

How to fine tune your asp net 2.0 app - Part 2

Comprimir el ViewState

La clase LosFormatter

jueves, 3 de septiembre de 2009

Windows Vista: ¿Que está haciendo éste hombre con Windows Vista?

Yo no tengo Windows Vista y me gustaría comprarlo más adelante sin embargo he escuchado durante varios meses que Windows Vista ¡nada que ver!; no me he tomado la molestia de bajar un versión de prueba pero me he puesto a leer algo al respecto. Y entre lectura y lectura encontré un video que demuestra la reacción de una persona que en definitiva no le gusto Windows Vista.



Este video tan cómico lo encontré en www.securitytube.net

CSS: Resetear CSS en todos los navegadores.

En meyerweb.com encontré unas cuantas reglas de CSS que permiten resetear los CSS predeterminados que vienen en los navegadores. Vale la pena probarlo.

El código es el siguiente:
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
body {
line-height: 1;
color: black;
background: white;
}
ol, ul {
list-style: none;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: separate;
border-spacing: 0;
}
caption, th, td {
text-align: left;
font-weight: normal;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: "";
}
blockquote, q {
quotes: "" "";
}

miércoles, 2 de septiembre de 2009

Asp.Net: ModalPopupExtender y evento onclick

Estaba implementando el control ModalPopupExtender pero quería que al presionar el botón que establecí para el atributo OkControlID, hiciera una tarea específica, por ejemplo, que actualice la propiedad Text de un Label. (El atributo CancelControlID también esta presente en el control ModalPopupExtender).

Ya existía del lado del servidor un código que se debía ejecutar cuando hago clic en dicho botón. El problema es que no se estaba ejecutando ese código. El código XHTML para el modalpopup es el que se muestra a continuación:


<div id="modalMsg" style="border: 0.01em dotted brown; display: none; width: 320px; height: 80px;">
<span style="font-weight: bold; margin-bottom: 20px;">¿Seguro que desea eliminar el
registro?</span>
<div>
<asp:button id="btnSi" runat="server" text="Sí" onclick="Msg()">
<asp:button id="btnNo" runat="server" text="No">
</asp:button></asp:button></div>
</div>

También se observan los botones btnSi y btnNo. Veamos que el atributo onclick está presente. Lo puse para ejecutar en el lado del cliente una simple función de ejemplo.

Para empezar, el atributo onclick en un botón del lado del servidor, no es compatible con controles del tipo "Web Serve Control". Lo que se debe usar es el atributo OnClientClick.
Si fuera un botón Html si funcionaría. Si yo dejo el onclick aparecerá un error indicando que la función Msg() no es parte del archivo ASP.default_aspx'. Por lo tanto, en vez de onclick hay que usar OnClientClick.

Pero aun queda el problema de que no se está ejecutando el método del lado del servidor. El código para el botón btnSi es el siguiente:
Protected Sub btnSi_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSi.Click
lblResultado.Text = "Hizo clic en el botón 'Sí'"
End Sub
El objetivo es que ese método del lado del servidor se ejecute sin problemas; es evidente que al usar ModalPopupExtender, dicha funcionalidad se pierde.

La solución es usar el atributo OnClientClick más una función que ejecute el método __doPostBack:
<div id="modalMsg" style="border: 0.01em dotted brown; display: none; width: 320px; height: 80px;">
<span style="font-weight: bold; margin-bottom: 20px;">¿Seguro que desea eliminar el
registro?</span>
<div>
<asp:button id="btnSi" runat="server" text="Sí" onclientclick="server('btnSi')">
<asp:button id="btnNo" runat="server" text="No" onclientclick="server('btnNo')">
</asp:button></asp:button></div>
</div>

<script type="text/javascript">
function server(arg) 
{
 __doPostBack(arg, '');
}
</script>

No obstante existe otra solución. Ya dijimos que los atributos OkControlID y CancelControlID se están utilizando. La segunda solución sería eliminar esos atributos del todo y listo, no es necesario hacer nada más.

En caso de que el Label este dentro de un control UpdatePanel, se debe registrar en el evento Page_Load el botón btnSi con:

ScriptManager1.RegisterAsyncPostBackControl(btnSi)

Eso hará que el Label se actualice asíncronamente si tener que refrescar toda la página. Un equivalente es registrar un Trigger para el botón dentrol del UpdatePanel.

Referencias:
Asp.Net Ajax

martes, 1 de septiembre de 2009

Ado.Net: Códigos valiosos.

ConfigurationManager
Dim cnn As New SqlConnection(ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString)
Response.Write(cnn.ConnectionString)

ConfigurationManager
System.Configuration.ConfigurationSettings.AppSettings["connstr"].ToString();

ConfigurationManager
ConfigurationManager.GetSection("prodSection")

ConfigurationManager
ConfigurationManager.GetWebAppSection("prodSection")

Agregar atributo a una fila de un GridView en Asp.Net:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='Silver'");
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='White'");
}
}

Insertar código JS:

Dim script As New StringBuilder
script.Append("")
Page.ClientScript.RegisterClientScriptBlock(Me.GetType, "MyScript", script.ToString)

Filtrar items que se van insertando en un Repeater control de Asp.Net:


Protected Sub Repeater1_ItemCreated(ByVal sender As Object,
ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater1.ItemCreated
Dim nav As XPathNavigator = CType(e.Item.DataItem, IXPathNavigable).CreateNavigator

For Each o As Object In e.Item.Controls
If TypeOf o Is HtmlAnchor Then
Dim pagina As String = nav.Select("/Titulos/Titulo").Current.SelectSingleNode("pagina").Value
If pagina = "Cursos" Then
If User.Identity.IsAuthenticated Then
Dim archivo As String = nav.Select("/Titulos/Titulo").Current.SelectSingleNode("archivo").Value

o.Attributes.Add("href", "media/images/" + archivo)
o.Attributes.Add("rel", "lightbox[roadtrip]")

Else
o.Attributes.Add("href", "/")
o.Attributes.Add("class", "verModal")
End If
Else
e.Item.Visible = False
End If
End If
Next
End Sub

CSS: Hoja estilo para maquetación básica.

Este es el CSS para maquetar una página con encabezado, tres columnas y un pie de página.

*
{
border: 0;
margin: 0;
}

body
{
font-family: Georgia,Arial, Helvetica, sans-serif;
font-size: medium;
}

/* Si el ancho cambia, hay que reajustar los porcentajes de
la columna central. */
.container
{
width: 800px;
margin: 0 auto;
border:0.01em dotted blue;
}

.header
{
width: 100%;
height: 120px;
background-color: Aqua;
border:0.01em dotted blue;
clear:both;
}

.leftColumn
{
width: 24%;
min-height: 400px;
border:0.01em dotted blue;
float:left;
}

.mainColumn
{
width: 51.2%; /* Ajustar si ancho de Container cambia. */
border:0.01em dotted blue;
min-height: 400px;
float:left;
}

.rightColumn
{
width: 24%;
border:0.01em dotted blue;
min-height: 400px;
float:right;
}

.footer
{
width:100%;
height:50px;
}

#separador
{
clear:both;
}

La estructura básica sería:

<div class="container">
<div class="header">
</div>
<div class="leftColumn">
</div>
<div class="mainColumn">
</div>
<div class="rightColumn">
</div>
<div id="separador">
</div>
<div class="footer">
</div>
</div>

CSS: Menú con CSS

Un ejemplo sencillo de menú horizontal o vertical lo podemos encontrar en www.cssblog.es

Otras referencias:

El iguiente link es interesante, presenta una lista de menus listos para descargar y lo mejor de todo es que se pueden modificar antes de descargarlos. El enlace es www.cssmenumaker.com

Para rematar, jeje! encontré en un blog que presenta una gran lista de sitios que hablan sobre creación de menus con CSS. El sitio es blogvecindad.com