RadioButtonList: Insertar llamada Javascript en ListItem

Ya sabemos utilizar facilmente el RadioButtonList pero como llamar a una funcion del lado del cliente (javascript) desde un LisItem, veamos un ejemplo

Tenemos un sencillo webcontrol RadioButtonList

<asp:RadioButtonList ID="RadioButtonList1" runat="server" >
<asp:ListItem Value="yoda">Yoda</asp:ListItem>
<asp:ListItem Value="luke">Luke Skywalker</asp:ListItem>
<asp:ListItem Value="r2d2">R2-D2</asp:ListItem>
<asp:ListItem Value="c3po">C-3PO</asp:ListItem>
</asp:RadioButtonList>
 
y un metodo a llamar en javascript
<script language="javascript" type="text/javascript">
       function mensaje(ctlOpcion){                
           alert("Opcion seleccionada: " + ctlOpcion.value);
       }        

</script>

Pero como agregamos llamada a un metodo del cliente? No tenemos a nuesta disposicion nada referente a lado del cliente
image

Entonces no nos queda mas remedio que ir al codigo…y agregarlo mediante el metodo Atributtes.Add (ya que es una coleccion)

Dim itemRadioBtn As ListItem
For Each itemRadioBtn In RadioButtonList1.Items
itemRadioBtn.Attributes.Add("onClick", "mensaje(this);")
Next
Vamos recorriendo los items de nuestro RadioButtonList y en el evento onClick (podria ser otro que necesitemos) vamos declarando la llamada a la funcion javascript.
 
Para verlo funcionar (aunque sea en imagen)
image

 

Tambien podriamos recorrer mediante javascript, una opcion seria sin conocer la cantidad de items

Veamos un script

<script language="javascript" type="text/javascript">
   1:  
   2:    function mensajeSeleccionado(ctrlOpcionesId){
   3:        alert("Opcion seleccionada:" + OpcionObtenerSeleccionada(ctrlOpcionesId))
   4:    }
   5:    
   6:    function OpcionObtenerSeleccionada(ctrlOpcionesId)
   7:        {
   8:            //Recorremos los items                   
   9:            var posicion = 0;
  10:            var item = document.getElementById(ctrlOpcionesId+"_"+posicion);    
  11:            alert(ctrlOpcionesId+"_"+posicion);                  
  12:            while(item != null){
  13:                  if(item.checked) {
  14:                    return item.value;
  15:                  } else{
  16:                    posicion += 1;
  17:                    item = document.getElementById(ctrlOpcionesId+"_"+(posicion));                                                                           
  18:                  }                        
  19:            }  
  20:        }    

</script>

 
Y lo llamamos con un enlace
<a href="javascript:mensajeSeleccionado('<%=RadioButtonList1.ClientId %>');">Ver Seleccion</a>

y enviamos el Id del lado del Cliente de nuestro webcontrol.

<a href="javascript:mensajeSeleccionado('<%=RadioButtonList1.ClientId %>', <%=RadioButtonList1.Items.Count %>);">Ver Seleccion</a>
(cabe aclarar que es mejro escribir esto desde el codigo y no inline como estamos utilizando <% %>)
Bueno y la firma de la funcion javascript seria
function mensajeSeleccionado(ctrlOpcionesId, cantidadItems){
alert("Opcion seleccionada:" + OpcionObtenerSeleccionada(ctrlOpcionesId, cantidadItems))
}

y recorrer mediante un bucle for… que te lo dejo para tarea del hogar 😉

 

Enlaces

  • RadioButtonList (Clase)
    Representa un control de lista que encapsula un grupo de controles de botón de opción.
  • ListItem.Attributes (Propiedad)
    Obtiene una colección de pares de nombre y valor de atributo para la clase ListItem que ésta no admite directamente.
  • AttributeCollection (Clase)
    Proporciona acceso de modelo de objetos a todos los atributos declarados en la etiqueta de apertura de un elemento de control de servidor ASP.NET. No se puede heredar esta clase.

Redireccionar el usuario dependiendo del Rol desde Login webcontrol

Un funcionalidad requerida desde el webcontrol Login es la redireccion a partir de un rol especifico, ya sea porque unos amigos lo necesitaban o por algunas preguntas de la misma tematica en los grupos de noticias de asp.net

Vamos por lo que nos dice la razón, que es en el evento LoggedIn. Porque se ejecuta en este orden: LoggingIn, Authenticate y luego LoggedIn

Un ejemplo:

Protected Sub Login2_LoggedIn(ByVal sender As Object, ByVal e As System.EventArgs) Handles Login2.LoggedIn
       If User.IsInRole("MAESTROJEDI") = True Then
           Response.Redirect("~/admin/indexParaMAESTROJEDI.aspx")
       End If
   End Sub

Pero no funciono..!!
No encontramos en ningun lado porque no teniamos al usuario disponible (en el objeto User), ni tampoco de esta manera:    

Roles.IsUserInRole(Context.User.Identity.Name, "MAESTROJEDI")

Pareciera que cuando recien termina de armar la pagina se carga en la session y las cookies son enviadas a cliente….pero antes nada de nada

No nos ibamos a quedar de brazos cruzados, algo teniamos que hacer. Llegamos a dos soluciones que espero que sean de utilidad

OPCION 1: Pagina o Handler que sea te intermediario
Desde la página de login la enviamos en el mismo evento (LoggedIn) a otra pagina que alli podamos realizar esta sencilla pregunta de Roles

OPCION 2: Un poco… (artesanal) pero nos
Bueno dijimos entonces donde esta el usuario? y via MSN je en el textbox dentro del webcontrol Login y ya sabiamos que el usuairo se autentico
asi que solo nos quedaba recuperarlo:

Dim usuario As String = Login2.UserName
If Roles.IsUserInRole(usuario, "MAESTROJEDI") Then
    Response.Redirect("~/admin/indexParaMAESTROJEDI.aspx")
End If

OPCION 2.1:
Tambien lo puedes recuperar directamente del textbox que rederiza el webcontrol Login para el nombre de usuario con el id “Username”  

Dim txtUsername As TextBox = CType(Login2.FindControl("Username"), TextBox)
    Dim usuario As String = txtUsername.Text
    If Roles.IsUserInRole(usuario, "JEDIMASTER") Then
        Response.Redirect("~/admin/indexParaJEDIMASTER.aspx")
    End If

 

 

Enlaces

  • Login (Clase)
    Proporciona los elementos de la interfaz de usuario para iniciar sesión en un sitio Web.
  • Login.LoggingIn (Evento)
    Se produce cuando un usuario envía información de inicio de sesión, antes de que tenga lugar la autenticación.
  • Login.Authenticate (Evento)
    Aparece cuando se autentica un usuario.
  • Login.LoggedIn (Evento)
    Aparece cuando el usuario inicia sesión en el sitio Web y se ha autenticado.

VB4: "XAML, I am your father" (by Tom Hollander)

Interesante “correspondencia” entre XAML y los .FRM de los viejos (que aun utilizo) proyectos de VB6 en un post de Tom Hollander titulado VB4: “XAML, I am your father” . Lo capte al post rapidamente por dos cosas VB y la sugerencia a Startwars 😉
Hace un paralelismo entre estos dos diferentes tipos de metadata. No espero realizar un debate (ni con mis compañeros de trabajo) , ademas mas de una vez manipulamos estos archivos .frm, o .vbp de VB6 para arreglar alguna mala referencia, incluso en una oportunidad arreglando el un menu en VB6

También esto de definir formularios con xml como metadata ya habia testeado cuando jugaba con Flex y sus .mxml (en sus etapas beta) y me parecia bueno.. solo que la herramienta lo generaba cuando haciamos drag & drop era una separada Dreamweaver (parecido ya que se tomo como base esto mismo). Encima necesitaba ejecutar un sevidor de aplicaciones Java, asi que despues de las beta perdi el rastro de esta tecnología espero algun dia volver a utilizarla (si vuelve Soda Stereo porque yo no je!)

 

XAML VB5 MXML
<wf:Form x:Class="XamlWinForms.Window1"
    xmlns:x="http://schemas.microsoft.com
/winfx/2006/xaml"
    xmlns:wf="clr-namespace:System.Windows.Forms;
assembly=System.Windows.Forms"
    xmlns:sys="clr-namespace:System;
assembly=mscorlib"
    Text="Window1" Height="300" Width="300"
    >
  <wf:Form.Controls>
    <wf:Panel BackColor="#00FFFF" Dock="Fill"
BorderStyle="Fixed3D">
      <wf:Panel.Controls>
        <wf:Button Text="Click Me!"
Left="50" Top="50"
Width="100" Height="50"
Click="Button_Click">
</wf:Button>
        <wf:ListBox Top="120" Left="20">
          <wf:ListBox.Items>
            <sys:String>Foo</sys:String>
            <sys:String>Bar</sys:String>
          </wf:ListBox.Items>
      </wf:ListBox>
      </wf:Panel.Controls>
    </wf:Panel>
  </wf:Form.Controls>
</wf:Form>
VERSION 5.00
Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   3090
   ClientLeft      =   60
   ClientTop       =   450
   ClientWidth     =   3690
   ForeColor       =   &H0000FFFF&
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   ScaleHeight     =   3090
   ScaleWidth      =   3690
   StartUpPosition =   3  'Windows Default
   Begin VB.Timer Timer1 
      Interval        =   1000
      Left            =   3000
      Top             =   2280
   End
   Begin VB.CommandButton Command1 
      Caption         =   "Press to Play"
      BeginProperty Font 
         Name            =   "MS Sans Serif"
         Size            =   9.75
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   495
      Left            =   720
      MaskColor       =   &H008080FF&
      TabIndex        =   0
      Top             =   2400
      Width           =   2175
   End
   Begin VB.Shape Shape1 
      FillColor       =   &H000000FF&
      FillStyle       =   0  'Solid
      Height          =   615
      Index           =   8
      Left            =   2280
      Shape           =   5  'Rounded Square
      Top             =   1080
      Width           =   495
   End
End
<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx=
"http://www.macromedia.com/2003/mxml"> <mx:WebService id="wsStock" wsdl="http://services.xmethods.net/soap/
urn:xmethods-delayed-quotes.wsdl"> <mx:operation name="getQuote"> <mx:request> <symbol>{symbol.text}</symbol> </mx:request> </mx:operation> </mx:WebService> <mx:Label text="Enter a symbol:"/> <mx:HBox> <mx:TextInput id="symbol"/> <mx:Button label="Get Quote"
click='wsStock.getQuote.send()'/> </mx:HBox> <mx:Label id="quote"
fontWeight="bold"
text="{wsStock.getQuote.result}"/> </mx:Application>

 

Buscando en Geeks.ms (que comunidad…!) encontre este interesante post del elBruno
   –  Migrando de VB6 a WPF … the easy way !!!
      Donde nos comenta sobre VB6(2)WPF
Me imagino que hace una correspondecia de estas propiedades que tenemos mas arriba, pero bueno el que necesita tiene algo para testear 😉

Y una frase al final que me gustaria reproducir: “it’s nice to know that good ideas like this don’t die”

Capturar salida de un proceso: Ejemplo comandos básicos (ping, tracert, cmd /?, etc)

Más de una vez quisimos llamadar a un .bat y recuperar la salida para visualizarla desde una página, con ASP.NET 2.0 tenemos metodos que nos facilitan la vida.
Como me dedique a leer un poco quise dejarlo por aquí, por si alguien lo necesita.

Siempre empezamos con un ejemplo bien pero bien básico para ir creciendo, y poder realizar las tareas que realmente necesitamos. En este caso empezamos con un ping y luego seguimos con un tracert a geeks.ms y una ayuda de cmd.exe /?

Código

Private Sub Ejecutar()
      Dim strArgumentos As String = "127.0.0.1"
      Dim strExe As String = "ping"

      'Armar el proceso a ejecutar
      Dim startInfo As System.Diagnostics.ProcessStartInfo = New System.Diagnostics.ProcessStartInfo(strExe, strArgumentos)

      'Para poder manupular la salida indicamos que no se ejecute el shell
      startInfo.UseShellExecute = False

      'Por definicion (o mejor dicho codificacion) debemos ajustarnos a los que nos dice "San MSDN" 
      '(...)UseShellExecute debe ser true si se desea establecer ErrorDialog en true(...)
      startInfo.ErrorDialog = False

      'Sin ventana...
      startInfo.CreateNoWindow = True

      'Deseamos manipular la salida del proceso, para ello debemos establecer que se redirija la salida
      startInfo.RedirectStandardOutput = True

      Try
          Dim p As Diagnostics.Process = System.Diagnostics.Process.Start(startInfo)

          'Leemos la salida (objeto StreamReader)
          Dim sr As System.IO.StreamReader = p.StandardOutput
          Dim cadenaSalida As String = sr.ReadToEnd()
          sr.Close()

          'La visualizamos en el textbox. Un ejemplo basico ;)...
          TextBox1.Text = cadenaSalida
      Catch ex As Exception
          TextBox1.Text = (ex.Message)
      End Try


  End Sub

 

Ejemplo 1: Ping

Comando: “ping 127.0.0.1”

Dim strArgumentos As String = "127.0.0.1"
Dim strExe As String = "ping"

image

Y en la salida capturada y visualizada en el Textbox

image

 

Ejemplo 2: Tracert

Comando: “tracert www.geeks.ms”

Dim strArgumentos As String = "www.geeks.ms"
Dim strExe As String = "tracert"

image

Salida capturada

image

 

Ejemplo 3: Ayuda de cmd.exe /?

Comando: “cmd.exe /?”

Dim strArgumentos As String = "/?"
Dim strExe As String = "cmd.exe"

image

Y en la salida capturada y visualizada en el Textbox

image

 

Hasta aquí llego el ejemplo básico, espero sea la base para otras necesidades.
Como podemos capturar la salida del proceso, podremos manipularla/filtrarla a nuestro antojo.

 

Enlaces

  • Process.Start (Método) (ProcessStartInfo)
    Inicia el recurso de proceso que se especifica mediante el parámetro que contiene la información de inicio del proceso (por ejemplo, el nombre de archivo del proceso que se va a iniciar) y asocia el recurso a un nuevo componente Process.
  • ProcessStartInfo.UseShellExecute (Propiedad)
    Obtiene o establece un valor que indica si se va a usar el shell del sistema operativo para iniciar el proceso.
    • (…)Si se establece esta propiedad en false, es posible redirigir las secuencias de entrada, salida y error (…)
    • (…)El valor de UseShellExecute debe ser true si se establece el valor de la propiedad ErrorDialog en true.(…)
  • ProcessStartInfo.ErrorDialog (Propiedad)
    Obtiene o establece un valor que indica si se va a mostrar un cuadro de diálogo de error al usuario si el proceso no se puede iniciar.
    • nuevamente: (…)UseShellExecute debe ser true si se desea establecer ErrorDialog en true(…)
  • ProcessStartInfo.CreateNoWindow (Propiedad)
    Obtiene o establece un valor que indica si el proceso se va a iniciar en una nueva ventana.
  • ProcessStartInfo.RedirectStandardOutput (Propiedad)
    Obtiene o establece un valor que indica si el resultado de una aplicación se escribe en la secuencia de Process.StandardOutput.
    • (…)Cuando un Process escribe texto en la secuencia estándar, dicho texto se muestra normalmente en la consola. Si se redirige la secuencia de StandardOutput, se puede manipular o suprimir el resultado de un proceso(…)
    • (…)Es preciso establecer el valor de UseShellExecute en false si se desea establecer el valor de RedirectStandardOutput en true. De lo contrario, al leer la secuencia de StandardOutput, se produce una excepción.(…)
  • Process.StandardOutput (Propiedad)
    Obtiene una secuencia utilizada para leer la salida de la aplicación.

[ASP.NET] Simple pero poderoso: Literal webcontrol

Justamente tenia este post en el tintero porque hace unos dias conversamos en los grupos de noticias de asp.net sobre la diferencia de webcontrol Literal y Label, y justamente hoy leí el post en Geeks.ms de Sergio Tarrillo: Diferencia entre un control Litral y un control Label (asi que los invito a leerlo con enlaces interesantes)

Asi que esta primera parte ya estaba escrita.
Si tenemos la famosa frase: “Que la fuerza te acompañe”, y utilizamos los dos controles para visualizar

<asp:Label ID="lblEjemplo" runat="server" Text="Que la Fuerza te acompañe."></asp:Label>
<br />
<asp:Literal ID="ltlEjemplo" runat="server" Text="Que la Fuerza te acompañe."></asp:Literal>

Como dice Sergio en tu articulo, renderiza en esto si vemos el HTML resultante…

<span id="ctl00_contenidoCentral_lblEjemplo">Que la Fuerza te acompañe.</span>
<br />
Que la Fuerza te acompañe.
(aqui el Id del Label en el browser del cliente quedo armado: ctl00_contenidoCentral_lblEjemplo, porque esta bajo un MasterPage)
 
Como decia en ese post que hago referencia, me parece formidable tener un control sencillo pero a la vez potente; O sea, no podemos asignar estilos como el Label (con la propiedad CssClass) es limitado en ese aspecto, pero poderozo por su simpleza (es mi opinion personal) ya que es parecido a un Response.Write de  los viejos como yo que usabamos (y usamos) ASP Clásico 😉
Esto tambien trae la una consecuencia, que es que puede mostrar cualquier cosa, un script por ejemplo :O , asi que hay que tomarlo con pinzas.
Lo que nunca me gusto es cuando definen al control como Reserva una ubicación en la página Web para mostrar texto estático.”, porque reserva me da idea de esa ubicacion si no la utilizo quedara en blanco, pero bueno es algo que estoy divagando a estas horas de la noche…
Pero centremonos en una propiedad del webcontrol Literal: Mode, y sus valores posibles (PassThrough, Encode, Transform)
  • PassThrough:
    No se modifica el contenido del control.
    Ejemplo:
    <asp:Literal ID="ltlEjemplo_PassThrough" runat="server" 
                        Text="Que la <strong>Fuerza</strong> te acompañe. N° 123"
                        Mode="PassThrough"></asp:Literal> 

    Salida:

    Que la <strong>Fuerza</strong> te acompañe. N° 123
     
  • Encode:
    Se codifica el contenido a HTML
    Ejemplo:
  • <asp:Literal ID="ltlEjemplo_PassThrough" runat="server" 
                        Text="Que la <strong>Fuerza</strong> te acompañe. N° 123"
                        Mode="Encode"></asp:Literal> 

    Salida:

    Que la &lt;strong&gt;Fuerza&lt;/strong&gt; te acompa&#241;e. N&#176; 123
    
    

    Interesante modo cuando queremos presentar contenido HTML, y mostrando el codigo formateado, sin tener que recurrir a HttpUtility.HTMLEncode

 

 

  • Transform:
    Los elementos del lenguaje de marcado no compatibles se quitan del contenido del control.
    Al decir que no es compatible: si el explorador admite HTML o XHTML el comportamiento es identico al modo PassThrough
    Ejemplo:
  • <asp:Literal ID="ltlEjemplo_PassThrough" runat="server" 
                        Text="Que la <strong>Fuerza</strong> te acompañe. N° 123"
                        Mode="Transform"></asp:Literal> 
    Salida:
    Bueno como no tengo instalado un navegador wap para testar imaginemos que realiza lo que dice 😉
    Si por ejemplo la etiqueta encierra un contenido <EtiquetaNoValida>Contenido</EtiquetaNoValida>, este contenido se envia, pero la etiqueta no.
 El valor por default es Transform.
 
 
 

Enlaces

  • Label (Clase)
    Representa un control de etiqueta que muestra texto en una página Web.
  • Literal (Clase)
    Reserva una ubicación en la página Web para mostrar texto estático.
  • Literal.Mode (Propiedad)
    Obtiene o establece un valor de enumeración que especifica cómo se representa el contenido del control Literal.

String to Stream: para enviarlo como Attachment

Intentando enviar un archivo adjunto desde un string, me tope con la incertidumbre de como pasar un cadena (string) a un stream (flujo) ya que el simple casteo me generaba error

Bueno la idea primeramente era enviar un correo adjunto mediante el metodo Add de la coleccion Attachment
   

correo.Attachments.Add(New Attachment(strmMemory, "Recordatorio.htm", "text/html"))

pero necesitaba un stream (flujo) y solo tenia el contenido en cadena, y no podia , hasta que llego la

System.IO.MemoryStream
(…)La clase MemoryStream crea secuencias que utilizan como almacén de respaldo la memoria en lugar de un disco o una conexión de red. MemoryStream encapsula los datos almacenados como una matriz de bytes sin signo que se inicializa al crear un objeto MemoryStream; también se puede crear una matriz vacía. Es posible obtener acceso directamente a los datos encapsulados en la memoria. Las secuencias de memoria pueden reducir la necesidad de archivos y búferes temporales en una aplicación.(…)

El ejemplo es algo asi:

Private correo As New System.Net.Mail.MailMessage

'...varias lineas de código despues...

Dim uniEnco As New UnicodeEncoding
Dim aBytes As Byte() = uniEnco.GetBytes(_correoContenido.Cuerpo)
Dim strmMemory As New MemoryStream(aBytes)
correo.Attachments.Add(New Attachment(strmMemory, "Recordatorio.htm", "text/html"))

y luego me dedique a predicarlo jeje! posteando más a modo de recordartorio y para el que lo necesite algunas vez.
(queria que este en Geeks.ms, ya que lo habia posteado en oto lugar)

Nota:
Luego de investigar por este problema me tope con método CreateAttachmentFromString (lo dice todo el nombre no?), pero como no podía ganarme el “string to stream”, decidi realizarlo de la otra forma , pero para la próxima lo uso.

 

Para los curiosos, los enlaces:

Setup Project: Insertar Crystal Report Merge Module

Hace un par de años las intalaciones de nuestros proyectos de VB6 lo haciamos (y  lo seguimos haciendo) con algunos herramientas free de instalación por ejemplo NSIS (Nullsoft Scriptable Install System), o con el famoso InstallShield (no tan free). Ya que con el setup que armaba el propio ambiente de desarrollo no nos conformaba con todas las tareas que debia realizar.
Pero esta vez iba ha utilizar un Proyecto de Instalación de Visual Studio de 2005 (incluso podemos hacer un deployment de los proyectos VB6 que aun tenemos)
Mi sorpresa, que es igual en cuando a las características de las herramientas anteriores que utilizaba: seleccionar archivos, indicar como se ubican o se van en la instalacion final o son unicamente para el proceso (ejemplo imagenes, iconos),…

[UPDATE 2008 08 08] Cambio del enlace para descargar los MergeModules. Al final del
artículo la actualización de enlaces

Antes que nada recomiendo leer un articulo que escribio Sergio Tarrillo

Deployment de Crystal Reports en Windows y Web con Visual Studio 2005 (y mas de Crystal Reports .NET)

Donde podemos encontrar un interesante manual sobre el tema. Lo que quiero mostrar aqui es como obtener el Merge Module para nuestro proyecto de instalacion.

Para crear un nuevo proyecto de Instalación

CrystalReportMergeModule000

Vamos agregando archivos, y las configuración para la instalación:

CrystalReportMergeModule003

No voy centrarme en este momento de toda la configuración que podemos realizar en un proyecto de instalación, tal vez mas adelante. Sino de los elementos necesarios para la redistribución de Crystal Report.

Pero llego el momento de colocar el paquete de redistribucion de Crystal Report .NET (para Visual Studio 2005) que seria la version 10.2 de CR (BusinessObjects.CrystalReports.NET.2.0)

Agregando Merge Modules

CrystalReportMergeModule002

Donde nos posiciona en la carpeta de los Merge Modules
        C:Program FilesCommon FilesMerge Modules
Esta carpeta esta predeterminada en nuestro sistemas para el los productos de Microsoft y de terceros coloquen alli sus archivos .msm para redistribuir sus componentes

Pero no tenia el modulo que estaba buscando que tenga que ver con el Crystal Reports for .NET Framework 2.0 (x86)

¿Y donde lo podia obtener?

[UPDATE 2008 08 08] Cambio del enlace para descargar los MergeModules. Al final del
artículo la actualización de enlaces

Es conveniente hacerlo desde la sitio oficial de Business Objects para la descarga del Crystal Reports Merge Modules for Visual Studio .NET 2005 (este enlace ya no funciona – Gracias Francisco por el
aviso)
, en cual descargamos el archivo

cr_net_2005_mergemodules_mlb_x86.zip

CrystalReportMergeModule005

y dentro del zip dentro:
CrystalReportMergeModule001
Que en un sencillo tutorial en el archivo .doc nos comenta que hagamo los mismos pasos anteriores pero antes copiemos este modulo de redistribución dentro de la carpeta que anteriormente te mencione para tenerla siempre a mano.

Bueno el costo en tamaño: Son 25Mb sumandos en mi archivo de instalación.

 

Otra alternativa

En la carpeta de
C:Program FilesMicrosoft Visual Studio 8SDKv2.0BootStrapperPackagesCrystalReports
Se encuentra el instalador para redistrbuir: CRRedist2005_x86.msi

CrystalReportMergeModule004 

http://msdn2.microsoft.com/en-us/library/fyh6k4k4(VS.80).aspx

 

 

[UPDATE 2008 08 08]

¿Y donde lo podia obtener?

Hoy (en el día de la ignauguración de los Juegos Olímpicos de Bejing) me
comenta Francisco en un post/comentario en este articulo que el enlace para la
descarga no funciona! 🙁
Cuando veo que el enlace:
   (error) http://support.businessobjects.com/communityCS/FilesAndUpdates/cr_net_2005_mergemodules_mlb_x86.zip.asp

Ahora todo parece estar en SAP 😉

Alli solamente filtrar y obtendremos los enlaces a los archivo que
necesitamos

 

 

Enlaces 

Crystal Reports Merge Modules  for Visual Studio .NET 2005
(Este enlace ya no funciona. Gracias Francisco por el aviso)

Para descargar: 
    
Business Objects Downloads for Crystal
Reports and Xcelsius
     https://www.sdn.sap.com/irj/sdn/businessobjects-downloads

Windows Installer Deployment Tasks 
http://msdn2.microsoft.com/en-us/library/ybshs20f(VS.80).aspx

How to: Create or Add Deployment Projects 
http://msdn2.microsoft.com/en-us/library/fyh6k4k4(VS.80).aspx

Setup and Deployment Projects 
http://msdn2.microsoft.com/en-us/library/wx3b589t(VS.80).aspx

How to: Add Merge Modules to a Deployment Project 
http://msdn2.microsoft.com/en-us/library/8x727h8b(VS.80).aspx

REPLACE("Windows Live Folder", "Windows Live SkyDrive"), y no morir en el intento

Estaba leyendo unos articulos del nuevo servicio “Live” (y tambien la tenia a mi querida hermana que necesita un lugar para llevar a todos lados que no sea un “reenvio a su correo”, ni MI pendrive)
En geeks teniamos este artículo de Cesar con un analogía con el storage de Gmail, pero mi querida hermana necesitaba un tutorial de como utilizar y mas aun cuando no podia acceder simplemente con su cuenta passport, por esa razon quise postearla y para que le pueda servir a alguien de ayuda o guia.
Ademas de tener un menamismo para entrar sin necesidad de cambiar de país, ya que esta por ahora solamente habilitado en algunos paises este servicio.

 

NewName_SkyDrive_WindowsLiveFolder

http://folders.live.com/

 

Pero cambio de nombre y ahora lo conoceremos como Windows Live SkyDrive

LiveFolder

http://skydrive.live.com/

De donde sale el nombre? para los curiosos…

 

LiveFolder000  

Me preparo para el ingreso… y …un hermoso mensaje
         “No disponible en tu región”
o su correspondiente version
         “Not available in your region”
:S …que es esto? una “entrega a domicilio”, o “pedido de pizza”?
Ya me habia sucedido algo asi con algunas funcionalidades de los servicios de Google (empezando con Gmail que para conseguir una cuenta beta habia que comprarla en ebay, suerte que tenemos amigos que nos brindaron desinteresadamente, cervceza de por medio)

Y ahora??

Queria probar (no me iba a quedar con las ganas)

Por unos minutos me teletransporte a otro lugar (unos cuantos kilometros) … vivo en Argentina, fui unos minutos a

  LiveFolder002

Donde cambiar esto??

En mi cuenta passport. Debes entrar en www.passport.com y alli modificar tu informacion de registro

 

Luego simplemente nos dirigimos a
http://folders.live.com/

y alli si…

 

image

Facil de entender para que son los tres tipos de carpetas.

Tamaño en la version beta… 500Mb (para todo el contenido de todas las carpetas)

LiveFolder003

 

Como crear carpetas

Podemos seleccionar una de las tres que vimos en la pagina principal

LiveFolder004

 

Subir Archivos

Opcion 1:
El viejo estilo o el que utilizamos al cargar un archivo en un email basado en web.

LiveFolder005

Opcion 2:
Una imagen basta…
LiveFolder006

Es un programa (para los entendidos un ActiveX, un programa que corre/se ejecuta en el explorador especificamente IE)

Y como se bloquea estas intalaciones, se necesita una “accion” por parte del usuario

LiveFolder007

LiveFolder008

LiveFolder009

LiveFolder010

que deberias permitir Instalar el Control ActiveX

 

Y con esto podemos “Arrastrar y Soltar” los archivos hacia la carpeta

 LiveFolder011

Vamos agregando archivos para luego presionar el boton “Cargar”

LiveFolder012

 

Y empieza la carga/subida de los archivos a la carpeta

LiveFolder013

Con un mensaje claro.. y preciso: “No cierres la ventana ni salgas de esta pagina”

LiveFolder014

 

Y los archivos esta en la nueva carpeta Wallpapers

LiveFolder015

 

Tenemos Vista Previa de los archivos (thumbs)
LiveFolder016

LiveFolder017

 

Y Algo que me gusto que lo lei aqui, poder incrustar la carpeta (las carpetas públicas)

LiveFolder018

LiveFolder019

Ejemplo aqui mismo mediante iframe

 

Pero no pude agregarlos a Mis Sitios de Red, ni menos abrirlo como una carpeta Web.
Esperemos que cuando no tenga mas la 4 letras (“beta”) podremos utilizarlo de esta forma.

 

Y mi cuenta? quedo con mi veloz viaje a otras tierras…

Para poder utilizar tuvimos que cambiar nuestro pais de origen por unos minutos, pero la sorpresa es que luego de volver a cambiar como estaba antes, a un pais de la lista de “no permitidos” :), pude seguir entrando a mis Carpetas de SkyDrive… asi que a probarlo.

Pero no me olvido de
GMail Drive
Que instala un disco virtual que hace uso de nuestro espacio en Gmail para guardar archivos, y lo vemos directamente como una disco en Mi PC
http://www.viksoe.dk/code/gmail.htm
gmail

 

Pero con un IPOD de 30GB soy autosuficiente 🙂

 

Mas info

Blogs del equipo de Live Folders
http://skydriveteam.spaces.live.com/

Un ejemplo con las carpetas del Equipo de SkyDrive
https://cid-977f793e846b3c96.skydrive.live.com/home.aspx

FreeTextBox y UpdatePanel (error renderizado)

El ambiente de trabajo sencillo, un ABM de una tabla con texto enriquecido asi que nos propusimos usar FTB (FreeTextBox), lo colocamos en dentro de un FormView y lo testeamos correctamente, hasta que se nos ocurrio la gran idea de insertar un UpdatePanel de ASP.NET Ajax, la ley de murphy se cumplia nuevamente, no renderizaba el contenido correctamente, el control se armaba pero el texto interior ni noticias.

Sintoma 1: El control lo visualizamos pero sin el contenido.
Sintoma 2: No respondia a ningun evento en sus botones o elementos (tab de modo html y modo diseño). Esto nos da un indicio que los elementos/recursos de script no estaba cargándose

Tenia algo asi…simple

       <FTB:FreeTextBox ID="ftbTramiteRequisitos" runat="server"
           Text='<%# Bind("TramiteRequisitos") %>'>
       </FTB:FreeTextBox>
FreeTextBoxYUpdatePanelErrorRender002

Probe con

       <FTB:FreeTextBox ID="ftbTramiteRequisitos" runat="server"             
            Text='<%# Bind("TramiteRequisitos") %>' 
            ButtonImagesLocation="externalFile" 
            JavaScriptLocation="externalFile" 
            ToolbarImagesLocation="externalFile"   
            SupportFolder="~/aspnet_client/FreeTextBox/"
            ScriptMode="InPage"  >
        </FTB:FreeTextBox>

y otras tanta alternativas más…Pero no queria colocar en la carpeta /aspnet_client/FreeTextBox/ los archivos necesarios (imagenes, .js, . xml) ya que para ASP.NET 2.0 todos los recursos necesarios estan embebidos en el mismo componente.

Al final googleando un poco, di con dos soluciones:

  1. Insertar dentro de un iframe, la cual no me convencia por lo compleja 😉 (aquí esta), y otra version no tan compleja aquí
  2. Registrar manualmente los scripts, que justamente alguien ya lo realizo (en los foros de FTB)

Entonces la solución:

  • El control: Lo dejo como estaba 
           <FTB:FreeTextBox ID="ftbTramiteRequisitos" runat="server"
               Text='<%# Bind("TramiteRequisitos") %>'>
           </FTB:FreeTextBox>
    Este control esta dentro de un formview, y este dentro de un UserControl
    (otras versiones aqui deberia estar todas las propiedades detalladas, pero en versiones recientes ya tiene asignadas valores predeterminados)
     
  • Y en la pagina donde utilizo el UserControl
     
    Public Overrides Sub RegisterStartupScript(ByVal key As String, ByVal script As String)
        ScriptManager.RegisterStartupScript(Me, GetType(Page), key, Replace(Replace(script, "FTB_AddEvent(window,'load',function () {", ""), "});", ""), False)
    End Sub


    Public Overloads Sub RegisterOnSubmitStatement(ByVal key As String, ByVal script As String)
        ScriptManager.RegisterOnSubmitStatement(Me, GetType(Page), key, script)
    End Sub


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            Page.ClientScript.RegisterClientScriptInclude("FTBFreeTextBox", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-FreeTextBox.js"))
            Page.ClientScript.RegisterClientScriptInclude("FTBUtility", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-Utility.js"))
            Page.ClientScript.RegisterClientScriptInclude("FTBToolbarItems", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-ToolbarItems.js"))
            Page.ClientScript.RegisterClientScriptInclude("FTBPro", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-Pro.js"))

        End If
    End Sub
 
      Esto tambien podrias estar y seria convenite en la MasterPage
     (la ubicacion de estos archivos es por defecto ~/aspnet_client/FreeTextBox/)
      Tendras que copiar los archivos de recursos (imagenes, js, xml) (esto viene al descargar FTB), generalmente busca en esta ubicación
              ~/aspnet_client/FreeTextBox/
       Pero la puedes cambiar pero tendras que setear estas propiedades (ademas de cambiar SupportFolder si cambias la carpeta)
     
    <FTB:FreeTextBox runat="server"
        Id="ftbTramitesRequisitos" SupportFolder="~/miCarpeta/FreeTextBoxRecursos" 
        JavaScriptLocation="ExternalFile"
        ToolbarImages="ExternalFile"
        ButtonImagesLocation="ExternalFile"  />

  Esta parte lo hice con archivos externos. Pero desde la version 3.0 viene todo esto embebido en la .dll y solo hay que agregar el handler en el web.config solo si estas trabajando con .NET 1.1

<httpHandlers>
     <add verb="GET" path="FtbWebResource.axd" type="FreeTextBoxControls.AssemblyResourceHandler, FreeTextBox" />
    </httpHandlers>
 

Varios SitemapProviders en la misma App Web (archivos .sitemap)

Una de las tantas preguntas frecuentes en los grupos de noticias de asp.net y tambien de algunos amigos es de como separar los items de menú principal (y más aún cuando hay elementos de secciones privadas o de administración), aqui coloco algunos tips a tener en cuenta y lo que podemos hacer. 

Filtrando los items del sitemap

En el origen de datos de sitemap tenemos la posibilidad de filtrar desde que nodo publicar los items del menu

<asp:SiteMapDataSource ID="SiteMapDataSourceMenuPrincipal"         
      runat="server"          
      StartingNodeUrl="~/admin/index.aspx" />

Esto es bueno cuando queremos que desde un subidirectorio solamente presentar en un submenu los items internos, pero…
De donde obtiene los items?

Como siempre digo la “magia” está en que hay un proveedor sitemap por defecto el cual obtiene los datos del web.sitemap, pero tenemos la posibilidad de agregar nuestros propios proveedores de mapas del sitio.
Para los que somos curiosos el proveedor por defecto se llama AspNetXmlSiteMapProvider y se encuentra en el web.config base, su ubicacion
C:WINDOWSMicrosoft.NETFrameworkv2.0.50727CONFIG

Separando los itemes (nodos) en archivos y como utilizarlos

Tenemos dos maneras de implementar en diferentes archivos el contenido de los items del sitemap

  1. En el mismo web.sitemap, asignar aun sitemapNode un archivo fisico separado
  2. Definir nuevos proveedores de sitemap en el web.config

 

OPCION 1: Para cada siteMapNone indicar en que archivo fisico se encuentran los items
Aqui podremos tener algo asi:

<siteMapNode siteMapFile="~/admin/Web.STARWARS.ADMIN.sitemap"></siteMapNode>

Donde el atributo puede ser:

  • Una referencia relativa a la aplicación, como ~/admin/Web.STARWARS.ADMIN.sitemap (teniendo en cuenta signo ~ hace referencia a la appweb)
  • Una ruta de acceso virtual, como /admin/… (como cualquier source en html)
  • Una referencia a la ruta de acceso relativa a la ubicación del archivo del mapa del sitio actual, como admin/Web.STARWARS.ADMIN.sitemap.

 

OPCION 2: Implementar nuevos proveedores de sitemap

Aqui deberiamos agregar a nuestro web.config en la seccion correcta un nuevo proveedor

<siteMap enabled="true">
    <providers>
        <add name="STARWARS.ADMIN.SiteMapProvider"
            description="Mapa del sector de Administracion"
            type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
            siteMapFile="~/admin/Web.STARWARS.ADMIN.sitemap" />
    </providers>
</siteMap>

Es una coleccion entonces podriamos tener varios

<siteMap enabled="true">
    <providers>
        <add name="STARWARS.ADMIN.SiteMapProvider" ...
        <add name="STARWARS.JEDIS.SiteMapProvider" ...
        <add name="STARWARS.SITHS.SiteMapProvider" ....

Incluso es conveniente para una mejor administración coloar un proveedor por defecto para no estar especificandolo luego en cada lugar que deseamos utilizarlo

<siteMap defaultProvider="STARWARS.JEDIS.SiteMapProvider" enabled="true">

Y mas aun si eliminamos los anteriores (el proveedor por defecto AspNetXmlSiteMapProvider), que como es una coleccion podemos hacer un clear

<siteMap defaultProvider="STARWARS.ADMIN.SiteMapProvider" enabled="true">
   <providers>
       <clear/>         
       <add...

Para utilizar tenemos la propiedad SiteMapProvider en el SiteMapDataSource

<asp:SiteMapDataSource ID="SiteMapDataSourceMenuPrincipal" 
        runat="server" 
        SiteMapProvider="STARWARS.ADMIN.SiteMapProvider"/>

 

 

Enlaces: