Mostrando entradas con la etiqueta moleskinformatico. Mostrar todas las entradas
Mostrando entradas con la etiqueta moleskinformatico. Mostrar todas las entradas

domingo, 1 de noviembre de 2009

MySQL (en Ubuntu) - Guía rápida

Nota:
Toda sentencia en MySQL debe terminar con un punto y coma (;).
El símbolo $ indica el símbolo de comando del interprete de comandos; por ejemplo,
en Windows es c:\>.El símbolo mysql> es el símbolo de comandos de MySQL. No se deben escribir con el comando ya que son auto-generados, al igual que el símbolo -> .

Instalación:
$sudo apt-get install mysql-server-5.1
Durante la instalación pedirá que se ingrese una contraseña para el root de mysql.
Vamos a crear una base de datos y un usuario con el que vamos a trabajar y que tendrá acceso a la nueva base de datos.
Para eso debemos conectarnos al servidor mysql mediante el comando:
$mysql -u nombredeusuario -p
Dado que en este momento sólo existe el usuario root; entonces, desde la consola o terminal escribimos el comando:
$mysql -u root -p
Nos pedirá la contraseña , así que la escribimos. Es de recordar que en la consola no aparecerá nada mientras escribimos la contraseña, así se evita que alguien más pueda verla.
Establecida la conexión aparecerá el símbolo de comandos:
mysql>
Creamos la nueva base de datos:


mysql>CREATE DATABASE newdb;

Creamos el usuario jlrvpuma y le damos permiso completo de acceso a la nueva base de datos newdb:


mysql>GRANT ALL ON newdb.* to jlrvpuma@localhost IDENTIFIED BY 'password';

Se ha creado al usuario “jlrvpuma” con contraseña “password” -puede ser cualquier cadena- y que tiene todos los permisos para la base de datos newdb y que se conectará a ella desde localhost.Si la conexión del cliente al servidor no fuera desde localhost, entonces se deberá cambiar localhost por el nombre del equipo pertinente.
A partir de este momento nos conectaremos a la base de datos con el usuario jlrvpuma:
$mysql -u jlrvpuma -p
Le indicamos a MySQL que vamos a utilizar la base de datos newdb:


mysql>USE newdb;


Creando una tabla:
Se usa la instrucción CREATE TABLE:


mysql> CREATE TABLE new_table(
-> user_id INT,
-> name VARCHAR(30),
-> last_name VARCHAR(40));


Visualizando tablas:
Se usa la instrucción SHOW TABLES :


mysql>SHOW TABLES;


Visualizando la estructura de una tabla:
Se usa la instrucción DECRIBE :


mysql>DESCRIBE new_table;


Insertando nuevos registros en una tabla:
Se utiliza la instrucción INSERT:


mysql> INSERT INTO new_table(user_id,name,last_name) VALUES(1,'Carlos','Villa');

También se puede hacer de una forma más sencilla:


mysql>INSERT INTO new_table VALUES(2,'Maritza','Rodriguez');

Pero se debe estar seguro del orden de los campos en la tabla, ya que se podría insertar datos en campos equivocados. Es recomendable usar la primera forma, de esa manera se reducen las posibilidades de errores, pues se puede apreciar el orden en que están siendo ingresados los campos.

Cambiando registros en una tabla:
Se usa instrucción UPDATE:


mysql>UPDATE new_table SET name='Yuri' WHERE user_id=2;


Eliminando registros en una tabla:
Se usa la instrucción DELETE:


mysql>DELETE FROM new_table WHERE user_id=4;

Se debe tener cuidado, ya que si no se especifica mediante WHERE qué registro debe ser eliminado, se borrarán todos los registros de la tabla.


Recuperando información de una tabla(o haciendo consultas):
Se usa la instrucción SELECT. Por ejemplo, si se quiere recuperar todos los campos, se usa el comodin *:


mysql> SELECT * FROM new_table;

O bien, si se quiere sólo algunos campos:


mysql> SELECT name,last_name FROM new_table;

usando la clausula WHERE:


mysql> SELECT name FROM new_table WHERE user_id=1;


Usando la instrucción LIKE y el comodín % :


mysql>SELECT * FROM new_table WHERE name LIKE 'Car%';

El símbolo % significa 0(cero) o más caracteres después de la cadena 'Car'.En otras palabras se recuperará los registros cuyo campo name empiece por 'Car'.
La instrucción :


mysql>SELECT * FROM new_table WHERE name LIKE '%r%';

recuperará todos los registros cuyo campo name empiece y termine por cualquier cadena pero que contenga la letra 'r'.
La instrucción :


mysql>SELECT * FROM new_table WHERE name LIKE 'M%a';

recuperará todos los registros cuyo campo name empiece con 'M' y termine en 'a'.

Usando la clausula ORDER BY:
También podemos combinar con la clausula ORDER BY para ordenar los resultado y podemos usar las palabras clave ASC y/o DESC para ordenar los resultados en orden ascendente o descendente respectivamente:


mysql> SELECT * FROM new_table ORDER BY name DESC;
mysql> SELECT * FROM new_table ORDER BY name ASC;

o bien:


mysql> SELECT * FROM new_table ORDER BY name ASC, last_name DESC;


Usando la instrucción DISTINCT :
Útil cuando tenemos valores repetidos en dos o más campos y queremos los resultados sin repeticiones:


mysql> SELECT DISTINCT name FROM new_table;

Usando la clausula LIMIT:
Permite limitar el numero de resultados o limite de fila, además permite establecer el desplazamiento; es decir el numero de fila desde dónde empezará a contar, la estructura sería mas o menos: LIMIT desplazamiento,límite de fila
La instrucción :


mysql>SELECT * FROM new_table LIMIT 1,2;

recuperará la segunda y tercera fila. El primer valor, a la izquierda de la coma, en la clausula LIMIT, se refiere al desplazamiento, en este ejemplo, al ser su valor 1, empezará a contar desde la segunda fila ya que se empieza a contar desde 0(cero). Se puede omitir el valor de desplazamiento, poniendo sólo el valor de la derecha o límite de fila, MySQL asumirá el valor 0(cero) como valor de desplazamiento predeterminado. La siguiente instrucción recuperará las dos primeras filas :


mysql>SELECT * FROM new_table LIMIT 2;


Usando funciones COUNT(), MAX(), MIN(),SUM(),AVG():
Para obtener el número de filas o registros:


mysql> SELECT COUNT(name) FROM new_table;

O bien si se quiere saber cuantos nombres diferentes hay:


mysql> SELECT COUNT(DISTINCT name) FROM new_table;


Para recuperar el mayor valor de un campo:


mysql> SELECT MAX(user_id) FROM new_table;



Para recuperar el menor valor de un campo:


mysql> SELECT MIN(user_id) FROM new_table;



Para recuperar la media :


mysql> SELECT AVG(user_id) FROM new_table;



Para recuperar el total de la suma de todos los valores de un campo:


mysql> SELECT SUM(user_id) FROM new_table;

martes, 13 de octubre de 2009

Casos de Uso

Los casos de uso no son parte del diseño (Cómo) sino parte del análisis (Qué), de manera que nos ayudan a describir qué es lo que el sistema debe hacer. Cada caso de uso proporciona uno o más escenarios que indican cómo debería interactuar el sistema con el usuario o con otro sistema para conseguir un objetivo específico.Considérese un procesador de texto, dos casos de uso típico serían: "poner texto en negrita" y "crear índice" , por medio de estos ejemplos , se puede uno dar una idea de ciertas propiedades de los casos de uso :
  • El caso de uso capta alguna función visible para el usuario.
  • El caso de uso puede ser pequeño o grande.
  • El caso de uso logra un objetivo discreto para el usuario.
En su forma más simple el caso de uso se obtiene hablando con los usuarios habituales y analizando con ellos las distintas cosas que deseen hacer con el sistema.
Se debe abordar cada cosa discreta que quieran , darle un nombre y escribir un testo descriptivo breve (sólo unos cuantos párrafos).
No trate de obtener todos los detalles justo desde el principio, los podrá obtener cuando los necesite.
Sin embargo, si considera que un caso de uso dado tiene ramificaciones arquitectónicas de importancia, necesitará más detalles a la mano.
Lo realmente útil de los casos de uso es el documento que describe el caso de uso, en este documento se explica la forma de interactuar entre el sistema y el usuario.
Siguiendo con el procesador de texto, este podría ser el caso de uso de guardar un documento:

Nombre: Guardar Documento
Autor: jlrvpuma
Fecha: 14/10/2009
Descripción:
Permite guardar un documento en el disco duro o cualquier medio de almacenamiento
Actores:
Usuario del procesador de texto
Precondiciones:
El usuario debe haber creado el documento
Flujo Normal:
  1. El actor pulsa sobre el botón para guardar el documento
  2. El sistema muestra una caja de texto para introducir el título del documento y una zona de mayor tamaño donde se muestra el árbol de directorios del sistema para elegir el directorio dónde sera guardado el documento
  3. El actor introduce el título del documento y elige el directorio donde se guardará el documento.
  4. El sistema comprueba la validez de los datos y los almacena.
Flujo Alternativo:
  1. El sistema comprueba la validez de los datos, si los datos no son correctos, se avisa al actor de ello permitiéndole que los corrija
Poscondiciones:
El documento ha sido almacenado o guardado

Me he saltado los campos Nombre,Autor,Fecha,Descripción ya que son evidentes y no necesitan explicación
Los actores son aquellos que interactúan con el sistema. Las precondiciones son los hechos que se han de cumplir para que el flujo de evento se pueda llevar a cabo.El flujo normal corresponde a la ejecución normal y exitosa del caso de uso.Los flujos alternativos permiten indicar que es lo que hará el sistema en situaciones anormales o inesperadas.Por ultimo, las poscondiciones son los hechos que se han de cumplir si el el flujo de eventos normal se ha ejecutado normalmente.
Los casos de uso se pueden detallar mas o menos dependiendo del problema.
Cabe señalar que el documento del caso de uso mostrado es incompleto, puedes ver una plantilla de caso de uso completa AQUI, se les suele llamar casos de uso "full-dressed".

Diagramas de Casos de Uso
UML define una notación gráfica para realizar diagramas de casos de uso.Los diagramas de casos de uso son a menudo confundidos con los casos de uso. Mientras los dos conceptos están relacionados, los casos de uso son mucho más detallados que los diagramas de casos de uso.Cuando empiezas a tener un número considerable de casos de uso como el anterior, no resulta nada fácil situarlos y relacionarlos. Entonces empiezas a tener la necesidad de una visión general del asunto, y ahora si, es cuando los diagramas de casos de uso son de utilidad.
Los casos de uso están representados por elipses y los actores están representados por las figuras humanas, estas son al notación estándar de los actores, sin embargo, algunos utilizan otras figuras como una imagen de un computador por ejemplo, para representar un actor.
La figura siguiente muestra algunos de los casos de uso de un sistema de financiamiento : (extraído del libro UML Gota a Gota)



Hay cuatro actores en la figura: el gerente de comercio, el comerciante, el agente de ventas y el sistema de contabilidad.En la mencionada organización probablemente habrá diversos comerciantes.Además, un usuario puede desempeñar varios papeles.Por ejemplo, un comerciante de edad madura podría desempeñar el papel de gerente de comercio y además ser un comerciante normal.Por otra parte, un comerciante puede ser también agente de ventas.Cuando se trata con actores, conviene pensar en los papeles o roles, no en las personas ni en los títulos de sus puestos.
Los actores llevan a cabo casos de uso.Un mismo actor puede realizar muchos casos de uso;a la inversa, un caso de uso puede ser realizado por varios actores.Obsérvese que no es necesario que los actores sean seres humanos, a pesar que estén representados por figuras humanas en el diagrama del caso de uso.El actor puede ser también un sistema externo que necesita información del sistema actual.En la figura se puede apreciar la necesidad de actualizar cuentas (caso de uso: actualiza cuentas) del sistema de contabilidad.
Además de los vínculos entre los actores y los casos de uso, hay otros tipos de vínculos en el diagrama de casos de uso del sistema de financiamiento.Estos representan las relaciones de uses y extends entre los casos de uso.

Se usa la relación uses cuando es necesario que el caso de uso original haga uso de otro caso de uso, como en la figura de arriba, tenemos el caso de uso Analiza Riesgo, este caso de uso hace uso del caso de uso Valuación, le es necesario para cumplir su tarea, bien podría ir Valuación dentro de Analiza Riesgo, es decir hacer un solo caso de uso, pero eso hará mas oscuro el caso de uso y lo que se busca es simplificar.
La relación extends se usa cuando el caso de uso original tiene como extensión otro caso de uso, sin necesario su utilización, se podría decir que enriquece al caso de uso original; piénsese, para darse una idea, en las extensiones de firefox...

domingo, 4 de octubre de 2009

Obteniendo Handle de una ventana mediante API´s - Windows

Se puede obtener el handle de una ventana mediante su título o nombre de clase a la que pertenece llamando a la función FindWindow contenida en la librería user32.dll.Para poder acceder a la función es necesario agregar la directiva:
using System.Runtime.InteropServices;

Declarar la función aplicando el atributo DllImport(definido en System.Runtime.InteropServices).Ademas, notar el modificador extern:

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowTitle);


Ahora podemos llamarla.Por ejemplo, abrimos el Bloc de notas, nos fijamos en el título de la ventana:
Sin título - Bloc de notas
(Depende en qué idioma esté el S.O)

Para obtener el handle de esta ventana llamamos a la función FindWindow ya declarada mandando como parámetro el titulo del Bloc de notas y al otro parámetro le enviamos un valor null:
IntPtr hWndNotepad = FindWindow(null,"Sin título - Bloc de notas");

Notar que el handle se recibe en un tipo IntPtr.Además, si la función falla retorna un valor Null.

Para comprobar que, efectivamente, hemos obtenido el handle de la ventana requerida haremos una prueba:Cambiar el titulo de la ventana.
Para cambiar el título de una ventana haré uso de la función SetWindowText contenida en la librería user32.dll.Así que la declaro como hice con FindWindow :
[DllImport("user32.dll")]
public static extern bool SetWindowText(IntPtr hWnd, string newTitle);


Ahora ya puedo cambiar el titulo del Bloc de notas, mando como parametro el handle de la ventana y un string con el nuevo titulo:
bool v = SetWindowText(hWndNotepad, "¡¡¡¡¡¡ esto funciona !!!!!!");


Para obtener el handle de la ventana en la que se trabaja; es decir, la activa,es necesario llamar a la función GetForegroundWindow, también contenida en la librería user32.dll.Así que la declaramos como las demás:

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();


Llamamos a la función:

IntPtr hWndActual=GetForegroundWindow();


Al final el código quedaría:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//para llamar a apis:
using System.Runtime.InteropServices;

namespace APIsExamples
{
class Program
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowTitle);
[DllImport("user32.dll")]
public static extern bool SetWindowText(IntPtr hWnd, string newTitle);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

static void Main(string[] args)
{
IntPtr hWndNotepad = FindWindow(null, "Sin título - Bloc de notas");
IntPtr hWndActual = GetForegroundWindow();
Console.WriteLine("El handle del Bloc de notas es {0}", hWndNotepad);
Console.WriteLine("El handle de la ventana activa es {0}", hWndActual);
Console.WriteLine("\nCambiando el titulo de ventana del Bloc de notas...");
bool v = SetWindowText(hWndNotepad, "¡¡¡¡¡¡ esto funciona !!!!!!");
Console.WriteLine("\nListo.La opreación ha devuelto un valor {0}",v);

Console.ReadKey();

}
}
}



Se puede recuperar los handle´s de las ventanas abiertas mediante la función GetWindow, aunque es mas eficiente hacerlo mediante la función EnumWindows.Esto se verá en otro post.

domingo, 21 de junio de 2009

Data Binding V - LaTeX

Código LaTeX

Ejemplo usando MultiBinding y MultiValueConverter .Lo que muestra es el código para generar una tabla en LaTeX:



Descargar
Nota: Se requiere el framework 3.5

jueves, 18 de junio de 2009

Data Binding IV

Multi Binding - IMultiValueConverter :
MultiBinding :
La clase MultiBinding describe una colección de objetos Binding asociados a una sola propiedad de destino de enlace.
MultiBinding permite enlazar una propiedad del destino de enlace a una lista de propiedades de origen y, a continuación, aplicar la lógica para generar un valor con las entradas indicadas.

IMultiValueConverter:
Proporciona una forma de aplicar la lógica personalizada a una clase MultiBinding.
Para asociar un convertidor a una clase MultiBinding, se debe crear una clase que implemente la interfaz IMultiValueConverter y, a continuación, los métodos Convert y ConvertBack.

En otras palabras, podemos tener múltiples propiedades de origen de enlace para una propiedad de destino de enlace.Sin embargo, la propiedad de destino de enlace sólo recibe una propiedad que no necesariamente es una de las de origen de enlace, sino el resultado de la lógica de conversion implementada en una clase que implementa la interfaz IMultiValueConverter.

Por ejemplo, la propiedad RenderTransform de un objeto Image recibe un objeto Transform que puede ser un ScaleTransform,RotateTransform,etc...
Para instanciar la clase RotateTransform se requieren -no necesariamente- tres valores de tipo double(angulo,coordenada X i Y del punto central de la rotación), los cuales se envían como parámetro a su constructor.

Ahora bien, Qué hago si tuviera una objeto Image al cual quisiera rotar de manera que el angulo de rotación y las coordenadas X i Y cambien en función de otros procesos?.

Pues, la respuesta es: MultiBinding + IMultiValueConverter.

Para hecerlo mas comprensivo he hecho un pequeño ejemplo.Una pequeña aplicación que rota un objeto Image en base a los valores de tipo double de la propiedad Value de tres Slider´s.
La propiedad RenderTransform(destino de enlace) del objeto Image, enlaza a tres propiedades de origen de enlace: la propiedad Value de cada Slider(líneas 33,34 y 35).

Muestro el código XAML :


   1:  <Window x:Class="TestWPF_Data_Binding_II.DataBinding_MultiBinding"

   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   4:      xmlns:local="clr-namespace:TestWPF_Data_Binding_II"

   5:      Title="DataBinding_MultiBinding" Height="740" Width="768">

   6:      <Window.Resources>

   7:          <local:DoubleRotateTransform x:Key="Convertidor"/>

   8:      </Window.Resources>

   9:      <Grid>

  10:          <Grid.RowDefinitions>

  11:          <RowDefinition Height="57*" />

  12:          <RowDefinition Height="124*" />

  13:          <RowDefinition Height="521*" />

  14:          </Grid.RowDefinitions>

  15:          

  16:          <TextBlock Text="MultiBinding" FontSize="22" Grid.Row="0" HorizontalAlignment="Center"/>

  17:          

  18:          

  19:          <Slider Grid.Row="1" Margin="53,11,125,0" Name="slider1"  VerticalAlignment="Top"

  20:                  Minimum="0" Maximum="1000"

  21:                  ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Value}"/>

  22:          

  23:          <Slider Grid.Row="1" Margin="53,50,125,52" Name="slider2" Minimum="0" Maximum="1000"

  24:                  ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Value}" />

  25:          

  26:         <Slider Grid.Row="1" Height="21" Margin="53,0,125,18" 

  27:                Name="slider3" VerticalAlignment="Bottom" Minimum="0" Maximum="360" 

  28:                 ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Value}"/>

  29:          

  30:         <Image Grid.Row="2" Margin="128,81,117,175" Name="image" Stretch="Fill" Source="/TestWPF_Data_Binding_II;component/rotsnake.gif">

  31:              <Image.RenderTransform>

  32:                      <MultiBinding Converter="{StaticResource Convertidor}">

  33:                          <Binding ElementName="slider1" Path="Value"/>

  34:                          <Binding ElementName="slider2" Path="Value"/>

  35:                          <Binding ElementName="slider3" Path="Value"/>

  36:                      </MultiBinding>

  37:              </Image.RenderTransform>

  38:          </Image>

  39:   

  40:      </Grid>

  41:  </Window>



Vemos que, entre las lineas 32 y 38, se han enlazado tres propiedades de origen de enlace, las propiedades Value de tres Slider´s, para una sola propiedad destino de enlace.Además, notamos que, en la línea 33, se especifica la propiedad Converter para el MultiBinding :
Converter="{StaticResource Convertidor}"
Esto significa que el recurso estático Convertidor esta apuntando a una clase que implementa la interfaz IMultiValueConverter.En efecto, la clase se llama DoubleToRotateTransform.Ha sido instanciada en la línea 7.

En el método Convert se desarrolla la lógica de conversion de los tres valores de tipo double de la propiedad Value de cada Slider y se retorna un objeto RotateTransform, el cuál si admite la propiedad RenderTransform del objeto Image.
Es conveniente señalar que, debido a que el modo del binding es OneWay,sólo es necesario implementar el metodo Convert.

A continuación la clase DoubleToRotateTransform :


using System;
//requerido para IMultiValueConverter:
using System.Windows.Data;
//requerido para ScaleTransform:
using System.Windows.Media;
//requerido para CultureInfo culture:
using System.Globalization;

namespace TestWPF_Data_Binding_II
{
public class DoubleToRotateTransform:IMultiValueConverter
{
/// <summary>
/// Metodo que recibe dos valores de tipo double
/// y retorna un ScaleTransform
/// </summary>
/// <param name="values">Colección de dos valores de tipo double</param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns>Retorna un ScaleTransform para la prop. RenderTransform de un image</returns>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double coorX = (double)values[0], coorY = (double)values[1], angulo=(double)values[2];

RotateTransform rt = new RotateTransform(angulo,coorX, coorY);
return rt;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
//Hacer conversiones si el modo es TWOWAY
throw new NotSupportedException("No se puede convertir");
}
}
}


Como se darán cuenta, los valores de las propiedades de origen de enlace pasan al metodo Convert como una colección de objetos(primer parámetro):
objetct[] values
Además, en la colección, estan en el orden en que fueron declarados en el enlace.Así, en la posición cero esta el valor dela propiedad Value de slider1; luego, en la posicion1, slider2 y finalmente slider3.


Nota: Cada propiedad Tooltip de cada Slider esta enlazando a la propiedad Value del mismo objeto al que pertenecen(líneas 21, 24 y 28):
ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Value}"

Captura :

domingo, 14 de junio de 2009

Data Binding WPF III

Cómo enlazar un Método :
El propósito del método es convertir Millas a Kilómetros. Recibe dos parámetros, un double especificando el valor de la distancia y un TipoDistancia especificando el tipo(Millas o Kilómetros).Retorna un String con el resultado de la conversión.
El metodo se llama Convertir y para eso he creado una clase llamada ConvertidorDistancia y también he creado la enumeración TipoDistancia:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestWPF_Data_Binding_II
{
public enum TipoDistancia
{
Millas,
Kilometros
}
public class ConvertidorDistancia
{
/// <summary>
/// Convierte Millas a Kilometros y viceversa.
/// </summary>
/// <param name="valorDist">Valor a convertir</param>
/// <param name="tipoDistancia">Tipo de Distancia</param>
/// <returns>Un string conteniendo el valor convertido</returns>
public string Convertir(double valorDist, TipoDistancia tipoDistancia)
{
if (tipoDistancia == TipoDistancia.Millas)
{
return (valorDist * 1.609344).ToString("0.##") + " km";
}
if (tipoDistancia == TipoDistancia.Kilometros)
{
return (valorDist * 0.621371192).ToString("0.##") + " m";
}
throw new ArgumentOutOfRangeException("tipoDistancia");
}

}

}


Para poder enlazar el método Convertir es necesario crear una instancia de la clase ConvertidorDistancia.Antes de hacerlo debemos agregar una referencia al espacio de nombre(namespace) donde se encuentra la Clase.En nuestro código Xaml sería la línea 4:
xmlns:local="clr-namespace:TestWPF_Data_Binding_II"

Donde local hace referencia al espacio de nombre TestWPF_Data_Binding_II.
Además he agregado system como referencia al espacio de nombres System(línea 5), pues ocuparé un objeto de tipo Double(línea 19).



   1:  <Window x:Class="TestWPF_Data_Binding_II.DataBinding_Method"

   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml
"

   4:      xmlns:local="clr-namespace:TestWPF_Data_Binding_II"

   5:      xmlns:system="clr-namespace:System;assembly=mscorlib"

   6:      Title="DataBinding_Method" Height="300" Width="300">

   7:      <Window.Resources>

   8:          

   9:          <!-- Instancia de la clase DoubleToString que impl
ementa a IValueConverter -->

  10:          <local:DoubleToString x:Key="doubleToString" />

  11:          

  12:          <!-- ObjectDataProvider pone al metodo como fuente de datos(origen de enlace/binding source) -->

  13:              <ObjectDataProvider

  14:              x:Key="ConvertirDistancia"

  15:              ObjectType="{x:Type local:ConvertidorDistancia }"

  16:              MethodName="Convertir" >

  17:                  <!-- Declaramos los parametros que recibe el metodo Convertir-->

  18:                  <ObjectDataProvider.MethodParameters>

  19:                      <system:Double>10</system:Double>

  20:                      <local:TipoDistancia>Millas</local:TipoDistancia>

  21:                  </ObjectDataProvider.Method
Parameters>

  22:              </ObjectDataProvider>

  23:      </Window.Resources>

  24:      

  25:      <Grid Margin="10">

  26:          <Grid.ColumnDefinitions>

  27:              <
ColumnDefinition Width="0.5*"/>

  28:              <ColumnDefinition Width="0.5*"/>

  29:          </Grid.ColumnDefinitions>

  30:          <Grid.RowDefinitions>

  31:              <RowDefinition Height="31" />

  32:              <RowDefinition Height="31" />

  33:              <RowDefinition Height="31" />

  34:          </Grid.RowDefinitions>

  35:          

  36:          <TextBlock Margin="5" Grid.ColumnSpan="2"

  37:                     VerticalAlignment="Center"

  38:                     Text="Ingrese una distancia para convertir :"/>

  39:          

  40:          <!-- Este TextBox enlazara al primer parametro del metodo Convertir  -->

  41:          <TextBox


  42:              Grid.Row="1" Grid.Column="0" Margin="5"

  43:              Text ="{Binding Source={StaticResource ConvertirDistancia}, Path=MethodParameters[0],

  44:                      BindsDirectlyToSource=true, UpdateSourceTrigger=PropertyChanged,

  45:                      Converter={StaticResource doubleToString}}"/>

  46:          

  47:          <!-- Este ComboBox enlazara al segundo parametro del metodo Convertir -->

  48:          <ComboBox

  49:              Grid.Row="1" Grid.Column="1" Margin="5" Width="80"

  50:              HorizontalAlignment="Left"

  51:              SelectedValue="{Binding

  52:                              Source={StaticResource ConvertirDistancia},

  53:                              Path=MethodParameters[1],

  54:                              BindsDirectlyToSource=true}" >

  55:              <local:TipoDistancia>Millas</local:TipoDistancia>

  56:              <local:TipoDistancia>Kilometros</local:TipoDistancia>

  57:          </ComboBox>

  58:          <TextBlock Grid.Row="2" HorizontalAlignment="Right" Margin="5"

  59:                     Text="Resultado:"/>

  60:          

  61:          <!-- Este TextBlock enlaza al resultado del metodo Convertir, es decir, lo que retorna.-->

  62:          <TextBlock Grid.Row="2" Grid.Column="1" Margin="5" 

  63:                     Text="{Binding Source={StaticResource ConvertirDistancia}}"/>

  64:          

  65:      </Grid>

  66:  </Window>



Ahora ya podemos instanciar la clase ConvertidorDistancia y tenerlo como recurso.Para eso debe ir dentro de:
<Window.Resources>
y
</Window.Resources>
.Y puesto que voy a enlazar el metodo Convertir debo instanciar la clase ConvertidorDistancia mediante la clase ObjectDataProvider.Esta clase ajusta y crea un objeto que se puede utilizar como origen de enlace.La operación comienza en la línea 13 y termina en la línea 22.
En la línea 14 le asignamos una clave a nuestro origen de enlace: x:Key="ConvertirDistancia"
En la línea 15 definimos el tipo de la instancia que creamos mediante el objeto ObjectType:
ObjectType="{x:Type local:ConvertidorDistancia }"
Mediante la propiedad MethodName definimos el metodo que es invocado por ObjectDataProvider:
MethodName="Convertir"
Dado que el metodo Convertir, el que enlazaremos, recibe dos parametros, los definimos mediante la propiedad de ObjectDataProvider: MethodParameters(Línea 18):
<ObjectDataProvider.MethodParameters>
Esta propiedad puede contener una colección de parametros.
Definimos el valor inicial del primer parametro.Será el valor 10 y será de tipo Double, ya que el primer parametro que recibe el metodo Convertir es un tipo Double(linea 19):
<system:Double>10</system:Double>
Tambien definimos el valr inicial del segundo parametro, el cual será Millas de tipo TipoDistancia(línea 20) :
<local:TipoDistancia>Millas</local:TipoDistancia>

Ya tengo listo el objeto para poder usarlo como origen de enlace.

Tenemos un TextBox(línea 41), un ComboBox(línea 48) y un TextBlock(línea 58).
La propiedad Text del TextBox enlazará al primer parametro del metodo Convertir.La propiedad SelectedValue del ComboBox enlazará al segundo parametro.La propiedad Text del TextBlock enlazará al metodo Convertir, es decir a su valor de retorno, el cual será un String.
En la línea 43 le decimos que nuestro origen de enlace(o fuente de datos) es el recurso estático llamado ConvertirDistancia.Recordemos que ConvertirDistancia es la clave del metodo Convertir,asi que apunta a este.Luego, definimos el valor de la propiedad Path.Aqui ocurre algo interesante.Vemos que la propiedad que queremos enlazar no es una propiedad del objeto que envuelve ObjectDataProvider(ConvertidorDistancia), sino que es una propiedad del mismo objeto ObjectDataProvider, la propiedad MethodParameters, y es el primer valor de la colección de parametros, osea el primer parametro, por eso la posicion cero:
Path=MethodParameters[0]
A continuacion vemos la propiedad BindsDirectlyToSource:
BindsDirectlyToSource=true
Esta propiedad establece un valor que indica si se va a evaluar la propiedad Path con respecto al elemento de datos(en este caso ConvertidorDistancia) o el objeto DataSourceProvider(en este caso ObjectDataProvider, ya que deriva de la clase abstracta DataSourceProvider).
El valor por defecto de esta propiedad es false.Cuando es false evalua la ruta de acceso con respecto al elemento de datos propiamente dicho; de lo contrario, es true, es decir, en nuestro caso evuluará la ruta de acceso respecto al obejto ObjectDataProvider.Esto debe ser así, ya que la propiedad Path tiene el valor de una propiedad de ObjectDataProvider(MethodParameters) y no del elemento de datos.
Luego tenemos la propiedad UpdateSourceTrigger:
UpdateSourceTrigger=PropertyChanged
Esto significa que desde el TextBox podremos actualizar el valor del origen de enlace, es decir el valor del primer parametro del metodo Convertir.El valor PropertyChanged significa que tan pronto haga un cambio en el TextBox actualizará el origen de enlace con el valor de la propiedad Text del TextBox.Finalmente tenemos la propiedad Converter del cual me ocuparé mas adelante.
En cuanto al ComboBox sucede casi lo mismo,excepto que va a enlazar al segundo parametro del metodo Convertir.Se definen los itemes de tipo TipoDistancia:
<local:TipoDistancia>Millas</local:TipoDistancia>
<local:TipoDistancia>Kilometros</local:TipoDistancia>

La propiedad Text del TextBlock enlaza al resultado del metodo Convertir, es decir a su valor de retorno:
Text="{Binding Source={StaticResource ConvertirDistancia}}"

La propiedad Source del Binding se usa para referenciar a una instancia de un objeto creado como recurso.

Propiedad Converter:
Se usa cuando es necesario convertir valores de propiedades antes de asignarse al destino de enlace o al origen de enlace.Para eso es necesario crear una clase que implemente la interfaz IValueConverter.La inetrfaz IValueConverter tiene dos metodos:
Convert y ConvertBack, donde podemos implementar cualquier conversion compleja.El metodo Convert es llamado cuando el modo de enlace es OneWay, es decir, cuando el origen de enlace modifica al destino de enlace(destino de datos).El metodo ConvertBack es llamado en el modo TwoWay, es decir, cuando el destino de enlace modifica el origen de enlace.
Cuando se especifica la propiedad Converter en un enlace o binding el valor del destino de enlace no se actualiza directamente desde el origen de enlace, sino que pasa primero por el método Convert, ahi se hace la conversion para retornar el valor apropiado que recibe el destino de enlace.
Para poder usarlo como un recurso es necesario instanciarlo.En nuestro ejemplo lo hicimos en la línea 10:
<local:DoubleToString x:Key="doubleToString" />
A continuación la clase que implementa a IValueConverter, se llama DoubleToString, aunque en el metodo ConvertBack mas bien convierte de string a Double:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//para implementar ivalueconverter
using System.Windows.Data;
//necersario para CultureInfo
using System.Globalization;

namespace TestWPF_Data_Binding_II
{

[ValueConversion(typeof(double), typeof(String))]
public class DoubleToString: IValueConverter
{
/// <summary>
/// Convierte Double a String.Antes de actualizar el valor del destino de enlace
///el valor pasa por este metodo para ser convertido a String.
/// </summary>
/// <param name="value">Objeto double</param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double val = (double)value;
return val.ToString();
}

/// <summary>
/// Covierte String a Double.Antes de actualizar el valor del origen de enlace
/// el valor pasa por este metodo para ser convertido a Double.
/// </summary>
/// <param name="value">Objeto string</param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
//throw new NotImplementedException();-->cuando no es necesario implementar el metodo.
double val = Double.Parse(value.ToString());
return val;
}


}
}


En nuestro ejemplo, el TextBox que enlaza al primer parámetro del metodo Convertir, recibe un string, ya que su propiedad Text soporta el tipo String.El modo del enlace es TwoWay(recordar la propiedad UpdateSourceTrigger), ya que podemos modificar el primer parámetro del metodo Convertir desde el TextBox.Aquí surge un inconveniente, la propiedad Text del TextBox contiene un String y el primer parametro del metodo Convertir es un tipo Double.En este momento entra en acción el metodo ConvertBack, es decir, antes de actualizar el origen de enlace(el primer parametro del metodo Convertir) el valor del destino de enlace (propiedad Text del TextBox) pasa por el metodo ConvertBack.Como notarán, en ese método el string se convierte a Double y se retorna un Double.Este Double es el que actualiza finalmente el primer parámetro del metodo Convertir.
Recordaran que se le habia asignado un valor inicial a los parametros del metodo Convertir(linea 19 y 20).Ocupemonos del primer parámetro:
Vemos que es el valor 10 de tipo Double.Tambien vemos que la propiedad que se enlazo al TextBox fue el primer parametro, es decir, un valor de tipo Double.Aqui entra en acción el metodo Convert.Antes de actualizar el TextBox con un Double desde el origen de enlace, el valor Double pasa por el metodo Convert, ahi se convierte a String y devuelve un String.Pues la propiedad Text del TextBox admite el tipo String.

Esa magia se logra implementando IValueConverter y especificando la propiedad Converter en el enlace:
Converter={StaticResource doubleToString}}
Aqui le decimos que Converter igual al recurso estático llamado doubleToString.Ya sabemos que es la clave de la clase DoubleToString.

captura:

sábado, 13 de junio de 2009

Data Binding WPF II

Enlazando un XML:



El codigo XAML:
namespace :TestWPF_Data_Binding_II
nombre de la ventana :DataBinding_XMLData



<Window x:Class="TestWPF_Data_Binding_II.DataBinding_XMLData"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataBinding_XMLData" Height="300" Width="300">
<Window.Resources>
<!--Usar la propiedad Source de XmlDataProvider si tenemos el archivo xml
referenciandolo con la Uri apropiada, como se muestra en el sgte codigo: -->
<!--<XmlDataProvider x:Key="PerrosXML"
Source="Perros.xml"
XPath="Perros"/>-->

<!-- O podemos embeber directamente el xml : -->
<XmlDataProvider x:Key="PerrosXML">
<x:XData>
<!--Si -cuando el xml va embebido- no se deja vacío el atributo xmlns, se producirá un
error, la salida será : "System.Windows.Data.Error exception has occurred"-->
<Perros xmlns="" >
<Perro Nombre="Alco" Color="Blanco" />
<Perro Nombre="Güeso" Color="Gris" />
<Perro Nombre="Pellejo" Color="Negro" />
</Perros>
</x:XData>
</XmlDataProvider>
</Window.Resources>

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition />
</Grid.RowDefinitions>

<TextBlock Text="Bind To XML Data" FontSize="15"
HorizontalAlignment="Center" Grid.Row="0" Margin="3" />
<TextBlock Text="Enlazando un archivo XML" FontSize="15"
HorizontalAlignment="Center" Grid.Row="0" Margin="29" />

<ListBox
ItemsSource="{Binding Source={StaticResource PerrosXML},
XPath=/Perros/Perro/@Nombre}"
Grid.Row="1" HorizontalAlignment="Center"/>
</Grid>
</Window>

domingo, 31 de mayo de 2009

Data Binding WPF

Explicación breve acerca de cómo usar data binding en wpf y ademas qué es data binding.
Disculpen las redundancias en la explicación, pero mejor dejar todo claro....

Modo One Way :



Modo Two Way :



Enlazar un objeto CLR - Modo Two Way :



Codigo - Visual Studio 2008:
Descargar

domingo, 3 de mayo de 2009

Patron de Creación Abstract Factory



Código de ejemplo escrito en C# :
Descargar (VS2008)
Descargar (MonoDevelop)



Video Explicación(1280x1024) :
Para ver mejor las letras se debe poner HD en ON(enviará a vimeo para verlo en HD).Creo que es lo mejor.

Abstract Factory - Design Pattern from jlrvpuma on Vimeo.


sábado, 11 de abril de 2009

Configurar APACHE 2 en Ubuntu Intrepid Ibex

Despues de haber instalado Apache2 exitosamente, podemos probar si el servidor funciona.En nuestro navegador favorito, escribimos en la barra de direcciones:
http://localhost
Y obtendremos algo como esto:
Si algún error ocurre debemos editar el archivo de configuración apache2.conf con el editor de texto que se prefiera, en este caso usaremos gedit :
$sudo gedit /etc/apache2/apache2.conf

Agregamos la siguiente linea en cualquier lugar del archivo de configuración:
ServerName localhost

Guardamos los cambios y luego reiniciamos Apache :
$sudo /etc/init.d/apache2 restart

Ahora probamos con localhost y si obtenemos el: "It works!", estamos listos para configurar Apache para que nos sirva nuestro propio sitio.

Creamos un nuevo sitio


Podemos crear un directorio de nuestro sitio en cualquier parte, en este caso se creará en :
$mkdir /home/usuario/mi_website

Ahora crearemos el archivo de configuración para el nuevo sitio.Podemos hacerlo a partir del archivo de configuración del sitio por defecto. Al nuevo archivo lo llamaré miweb :
$sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/miweb

Abrimos el nuevo archivo de configuración:
$sudo gedit /etc/apache2/sites-available/miweb

Buscamos la línea:
DocumentRoot /var/www/

Y cambiamos la ruta por la del directorio que creamos anteriormente:
DocumentRoot /home/usuario/mi_website

Luego buscamos la línea :
Y modificamos la ruta, con lo que deberá quedar así:


Guardamos los cambios.
A continuación deshabilitamos el sitio por defecto, deshabilitando su archivo de configuración, el cual es default.Para eso usamos el script de Apache:
$sudo a2dissite default

Seguidamente activamos nuestro nuevo sitio, habilitando su archivo de configuración.Para eso usamos otro script de Apache:
$sudo a2ensite miweb

Finalmente reiniciamos apache:
$sudo /etc/init.d/apache2 restart

Para probar si todo ha salido bien podemos crear un archivo index.html y guardarlo en :
/home/usuario/mi_website

Antes de ingresar a nuestro nuevo sitio, limpiamos la cache del navegador, en Firefox esta en Herramientas/Limpiar datos privados.
Ahora ya podemos ingresar a nuestro nuevo sitio. Escribimos en el navegador:
http://localhost

Y Listo. Ya tenemos nuestro servidor funcionando.

Fuente : www.zaphu.com