martes, enero 25, 2011

Uso de tuplas de C#

Ejemplo de definición de una función que retorna una tupla:


/// 
/// Retorna la asignación (técnico y mail) asociado a cierto tipo de elemento (equipamiento), o, en su defecto, de la categoría a la que pertenece.
/// 
/// Categoría del elemento
/// Tipo del elemento
/// Tupla Técnico/MailTo
public Tuple<Userstring> GetAssignmentForEquipmentType(string equipmentCategoryID, string equipmentTypeID)
{
    using (AIMModelConnection dc = new AIMModelConnection())
    {
        var query =
            from p in dc.EquipmentAssignments
            where (p.EquipmentCategoryID == equipmentCategoryID && p.EquipmentTypeID == equipmentTypeID) || (p.EquipmentCategoryID == equipmentCategoryID && p.EquipmentTypeID == null)
            orderby p.EquipmentCategoryID, p.EquipmentTypeID descending
            select p;
 
        EquipmentAssignment assignment = query.FirstOrDefault<EquipmentAssignment>();
 
        if (assignment != null)
            return Tuple.Create<Userstring>(assignment.User, assignment.CopyMailTo);
        else
            return null;
    }
}


... Y uso

// Obtener asignación en función de categoría y tipo del elemento afectado.
Tuple<Userstring> assignment = GetAssignmentForEquipmentType(equipmentCategory, equipmentType);

if (assignment != null)
{
    if (assignment.Item1 != null)
        this.txtAssignedTo.Text = assignment.Item1.UserName;

    if (assignment.Item2 != null)
        this.txtMailTo.Text = assignment.Item2;
}

viernes, enero 21, 2011

Otra forma de establecer/cambiar en tiempo de ejecución el valor de cualquier propiedad (Texto, Color, Icono...) de una celda de un GridView de ASP.Net

/// Método de evento de la columna State del grid, para modificar su valor (pasarlo a texto)
/// y su color en función del valor.
/// Se llama utilizando la propiedad Text='<%# Eval("State")%>', 
/// de un asp:Label, de un ItemTemplate, de un asp:TemplateField, del asp:GridView
protected void gridViewLabelState_Load(object sender, EventArgs e)
{
    Incident.StateEnum state = (Incident.StateEnum)int.Parse(((Label)sender).Text);

    ((Label)sender).ForeColor = IncidentStateColor.GetStateColor(state);
    ((Label)sender).Text = Incident.IncidentStateEnumToString((Incident.StateEnum)state);
}

Cómo establecer/cambiar en tiempo de ejecución el valor de cualquier propiedad (Texto, Color, Icono...) de una celda de un GridView de ASP.Net

A continuación un ejemplo de un grid con 2 columnas configuradas para que:
1ª) Muestre un texto y un color dependiendo del valor de un campo numérico.
2ª) Muestre una imagen en función del valor de 2 campos. 

[MiPagina.aspx (Diseño de página)] 


<asp:GridView ID="grdIncidents" runat="server" CellPadding="4" ForeColor="#333333"
    GridLines="None" AutoGenerateColumns="False" DataKeyNames="ID" AllowPaging="False"
    AllowSorting="True" Width="100%" CssClass="GridViewStyle">
    <Columns>
        <asp:TemplateField HeaderText="Estado" HeaderStyle-HorizontalAlign="Left">
            <ItemTemplate>
                <asp:Label ID="gridViewLabelState" DataField="State" runat="server" 
                    ForeColor='<%# GetStateColor(Eval("State"))%>' 
                    Text='<%# IncidentStateToString(Eval("State"))%>'/>
            ItemTemplate>
        asp:TemplateField>
        <asp:TemplateField HeaderText="" HeaderStyle-HorizontalAlign="Left">
            <ItemTemplate>
                <asp:Image ID="gridViewImageSemaforo" runat="server" 
                    ImageUrl='<%# GetSemaphoreImageUrl(Eval("State"), Eval("CreationDate"))%>' />
            ItemTemplate>
        asp:TemplateField>
    Columns>
asp:GridView>


[MiPagina.aspx.cs (Code behind)]

/// Método llamado desde la pantalla para convertir la columna State a texto.
protected string IncidentStateToString(object state)
{
    return Incident.IncidentStateEnumToString((Incident.StateEnum)state);
}

/// Método llamado desde la página para cambiar el color de un State.
protected System.Drawing.Color GetStateColor(object state)
{
    return IncidentStateColor.GetStateColor((Incident.StateEnum)state);
}

/// Método llamado desde la página para establecer el semáforo a partir del estado y
/// la fecha de creación.
/// Si la incidencia está esperando por un Técnico y lleva abierta más de 1 semana => Rojo!
/// Si la incidencia está esperando por un Técnico pero NO lleva abierta más de 1 semana => Ámbar
/// En cualquier otro caso (la incidencia no está esperando por un Técnico)
/// Estado de la incidencia
/// Fecha de creación de la incidencia
/// String de la url de la imagen del semáforo que toque.
protected string GetSemaphoreImageUrl(object state, object creationDate)
{
    // Si la incidencia está esperando por un Técnico...
    if (Incident.GetStatesFromStatus(Incident.StatusEnum.WaitingForTechnic).Contains<int>((int)state))
        //...y abierta desde hace más de 1 semana => Rojo!
        if (DateTime.Compare( ((DateTime)creationDate).AddDays(7), DateTime.Now)>0)
            return "Resources/semaphoreRed.png";
        //...y abierta desde hace menos de 1 semana => Ámbar
        else
            return "Resources/semaphoreYellow.png";

    // En caso contrario (la incidencia no está esperando por un Técnico)
    else
        return "Resources/semaphoreGreen.png";
}

martes, enero 11, 2011

Llenar un DataGridView sin usar Dataset (Populate a DataGridView without a DataSet)

Podemos llenar un DataGridView asignando a su DataSource una lista de objetos tal como se muestra en el ejemplo 1.


Nota: Los objetos deben exponer sus propiedades mediante construcciones get/set. Aquellas propiedades que no se expongan así, no se mostrarán en el DataGridView aunque sean públicas.


Una forma alternativa sería crear una clase que derive de IListSource (por ejemplo) e implementar el método GetList(), tal como se muestra en el ejemplo 2. Podemos crear un método Add(). En este caso el argumento estará tipado, cosa que en el anterior aceptaba cualquier tipo derivado de Object.


El interface IBindingList aportará funcionalidad extra con el DataGridView.


Un link con un ejemplo muy completo: http://msdn.microsoft.com/en-us/library/ms404297.aspx


Ejemplo 1:


Form_Load()

{

IList myBusinessObjectsList = new List();
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil B", "1..6"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil C", "1..7"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 3", "Perfil D", "1..8"));

this.dataGridView1.DataSource = myBusinessObjectsList;

}


public class MyBusinessObject
{

private string _group;
private string _perfil;
private string _range;
public string Group
{
get { return _group; }
set { _group = value; }
}
public string Perfil
{
get { return _perfil; }
set { _perfil = value; }
}
public string Range
{
get { return _range; }
set { _range = value; }
}
public MyBusinessObject(string group, string perfil, string range)
{
Group = group;
Perfil = perfil;
Range = range;
}
}


Ejemplo 2:


private void Form_Load(object sender, EventArgs e)
{
MyBusinessObjectsList myBusinessObjectsList = new MyBusinessObjectsList();
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil B", "1..6"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil C", "1..7"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 3", "Perfil D", "1..8"));
this.dataGridView1.DataSource = myBusinessObjectsList;
}


public class MyBusinessObjectsList: IListSource
{
List ls = new List();

#region IListSource Members
bool IListSource.ContainsListCollection
{
get { return false; }
}
System.Collections.IList IListSource.GetList()
{
return ls;
}
#endregion

public void Add(MyBusinessObject businessObject)
{
ls.Add(businessObject);
}
}

lunes, enero 10, 2011

Publicar aplicación

Desde Visual Studio 2010 es muy fácil "publicar" un proyecto (puede ser cualquier tipo de aplicación, web o desktop) utilizando la opción Generar / Publicar MiApp, tanto en una unidad compartida, como en un ftp o una web.

Por ejemplo:
Ubicación para la publicación: ftp://192.168.1.187/WWW/MiApp/.
Instalación: http://www.jaac.com/MiApp/

Al entrar desde un cliente a http://192.168.1.187/MiApp/publish.htm aparecerá un botón para iniciar la instalación de la aplicación, indicándonos los requisitos previos (versión de .Net Framework, etc)

Acceder a datos de una hoja excel

Para acceder a los datos de un excel podemos crear una función como la siguiente:

public DataTable GetExcel(string filename, string sheetName)
{
    OleDbConnection dbConn = null;
    DataTable resultTable = new DataTable(sheetName);

    // Build connection string.
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
        "Data Source=" + filename +
        ";Extended Properties=Excel 8.0;";

    // Create connection and open it.
    dbConn = new OleDbConnection(connString);
    dbConn.Open();

    if (!sheetName.EndsWith("$"))
    {
        sheetName += '$';
    }
    string query = string.Format("SELECT * FROM [{0}]", sheetName);

    using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, dbConn))
    {
        adapter.Fill(resultTable);
    }

    return resultTable;
}

Y en nuestro código usarla así:

    […]


    DataTable clientes;
    clientes = GetExcel(Application.StartupPath + @"\MiExcel.xls", "Hoja1"); // Buscará el fichero donde esté el exe.

    int numFilas = clientes.Rows.Count; // Cuidado, la primera fila se considera de títulos!

    string nombre = clientes.Rows[5]["Nombre"].ToString(); // Valor de la fila 5 y columna con título “Nombre”.

    […]

miércoles, enero 05, 2011

Joomla!, un open-source CMS

Desarrollado en php sobre mySQL. Permite a los desarrolladores crear sistemas de control de inventario, herramientas de reporting, catálogos de productos, e-Commerce integrado, herramientas de comunicación, etc.

Free controls para VStudio

DevExpress ofrece más de 60 controles para desarrollar aplicaciones WinForms, ASP.NET y Silverlight.

PHP CRUD Scaffold

www.phpscaffold.com permite generar online un mantenimiento en php sobre mySQL.

AjaxCRUD, un generador de mantenimientos php

AjaxCRUD es una clase php open-source que te permite conectarte a bases de datos mySQL y crear mantenimientos rápidamente. Más info en www.ajaxcrud.com.

NConstruct, un generador de .Net

NConstructor es una aplicación que te permite crear aplicaciones .Net, web y desktop, con mantenimientos CRUD a partir de una base de datos. Existe una versión reducida gratuita; la completa tiene 30 días de prueba. Más info en http://www.nconstruct.com/.

Jabaco, VB -> Java

Jabaco es un IDE que te permite convertir un proyecto VB a Java. El proyecto se puede compilar como .exe o como .jar. Éste segundo se puede ejecutar sobre cualquier máquina que tenga instalada la VM de Java, e incluso incrustarlo en una página html para ejecutarlo a través de la web. A día de hoy está en versión beta y es gratuito (al menos de momento).

Publicación web de pdf's a través de ISSUU

Existe una web, http://www.issuu.com/, que proporcionan un "object" incrustable en un fichero html, que en ejecución muestra una ventana con el pdf de una forma más interactiva y atractiva que el simple pdf.

Alias para un servidor Apache (o IIS)

En c:\windows\system32\drivers\etc existe un fichero llamado hosts editable con Notepad en el cual se pueden añadir lineas de alias a servidores. Por ejemplo:

192.168.1.187 www.jaac.com

Con esta linea, puedo escribir en el explorer www.jaac.com/xxx, donde xxx es cualquier cosa que tenga en el directorio web.

NOTA: Es posible que haya que modificar permisos en este fichero para poder editarlo.