martes, 28 de octubre de 2014

Mapear un campo numerico que puede ser nulo a un atributo de un objeto

Cuando tenemos un código como el siguiente:
if (dt.Rows.Count > 0)
     {
      this._holderID = int.Parse(dt.Rows[0]["holder_id"].ToString());
      this._item = int.Parse(dt.Rows[0]["item"].ToString());
      this._holderType = dt.Rows[0]["htype_id"].ToString();
      this._qty = int.Parse(dt.Rows[0]["qty"].ToString());
      this
._prodID =int.Parse(dt.Rows[0]["prod_id"].ToString());
      this._woID =int.Parse(dt.Rows[0]["wo_id"].ToString());
      this._stat = Stat.Loaded;
     }


en el cual tratamos de mapear los campos prod_id y wo_id a las variables _prodID y _woID de un objeto nos provoca un error al tratar de pasar un string vacio a entero en el caso de que ese campo de la tabla este vacío.
La solución es muy simple solo hay que comprobar primero si el campo esta vacío, en ese caso le ponemos un valor por omisión (en este caso 0), y en caso de que el campo no este vacio lo convertimos a entero y lo asignamos a la variable de nuestro objeto:


El codigo resultante quedaría asi:


if (dt.Rows.Count > 0)
     {
      this._holderID = int.Parse(dt.Rows[0]["holder_id"].ToString());
      this._item = int.Parse(dt.Rows[0]["item"].ToString());
      this._holderType = dt.Rows[0]["htype_id"].ToString();
      this._qty = int.Parse(dt.Rows[0]["qty"].ToString());
      this._prodID = dt.Rows[0]["prod_id"].ToString().Trim() == string.Empty ? 0 : int.Parse(dt.Rows[0]["prod_id"].ToString());
      this._woID = dt.Rows[0]["wo_id"].ToString().Trim() == string.Empty ? 0 : int.Parse(dt.Rows[0]["wo_id"].ToString());
      this._stat = Stat.Loaded;

     }



Como podemos observar la solución es simple.
Happy Coding!!!

Metodos para buscar en una lista

Cuando quieran encontrar elementos en una lista de objetos pueden usar ciclos, aunque es mejor utilizar los metodos búsqueda Find, FindAll,  Exists e IndexOf.

Obtener el elemento con Find

En lugar de utilizar un bucle foreach con un if , se puede utilizar el método Find en la lista.  Devuelve el primer objeto encontrado..
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int>(new int[] { 19, 23, 29 });

        // Encuentra el primer elemento mayor a 20
        int result = list.Find(item => item > 20);

        Console.WriteLine(result); // 23
    }
}
Descripción. Este código recorre cada valor int en la lista desde el principio y prueba cada valor para ver si es mayor a 20, y devuelve el primer valor encontrado (en este caso el numero 23). 
Un ejemplo mas completo:
Supongamos que tenemos la siguiente clase:
public class Employee{        public String EmpCode;    
    public String FirstName;    
    public String LastName; 
   
    public DateTime DateOfBirth;
    public String Department;
    public String Designation;
    //Constructor
    public Employee(String ecode, String fname, String lname, DateTime dob, String dept, String desg)
    {
         EmpCode = ecode;
         FirstName = fname;
         LastName = lname;
         DateOfBirth = dob;
         Department = dept;
         Designation = desg;    
    }
}
y tenemos una lista de objetos de tipo Employee...
public class EmployeeList : List<Employee>{ }  
en la cual agregamos los siguientes empleados...
EmployeeList elist = new EmployeeList();
elist.Add(new Employee("1","Ruben","Jacome",DateTime.Now,"Ingenieria de Manufactura","Programador"));
elist.Add(new Employee("2","Alejandra","Cruz",DateTime.Now,"Desarrollo de Software","Programador"));
elist.Add(new Employee("3","Mario","Gonzalez",DateTime.Now,"PCL","Supervisor"));
elist.Add(new Employee("4","Bob","Meyer",DateTime.Now,"Divisional","Gerente"));
y ahora buscamos a Bob...
Employee em = elist.Find(delegate(Employee e) { return e.FirstName == "Bob"; });
Ahora tendremos en em el objeto Employee que tenga el FirstName = "Bob".
Nota sobre las búsquedas hacia atras. Para buscar hacia atrás, utilice el método FindLast, que volvería a 29 en el ejemplo anterior. Analizará la lista desde el último elemento hasta el primero.
Buscar por otros métodos. También hay métodos FindIndex y FindLastIndex que se pueden utilizar para regresar el índice de los valores encontrados en la busqueda

Entendiendo FindAll

El método FindAll devuelve una lista de objetos del mismo tipo con todos los elementos que coinciden con la busqueda.

Utilizando Exists

El método Exists devuelve true o false dependiendo de si cualquier elemento coincide con el parámetro de busqueda.
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int>();
        list.Add(7);
        list.Add(11);
        list.Add(13);

        // Busca si existen valores mayores a 10
        bool exists = list.Exists(element => element > 10);
        Console.WriteLine(exists); // True

        // Busca por numeros menores a 7
        exists = list.Exists(element => element < 7);
        Console.WriteLine(exists); // False
    }
}
Descripción: En este ejemplo se prueba primero para ver si algun elemento de la lista tiene un valor mayor a 10, el cual regresa true. Despues, prueba por valores menores a 7, los cuales regresan false. 

Usando IndexOf

El método IndexOf tiene dos sobrecargas. Acepta el valor que desee encontrar como primer parámetro y, a continuación, devuelve la ubicación del valor en un arreglo.
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> primes = new List<int>(new int[] { 19, 23, 29 });

        int index = primes.IndexOf(23); // Existe en la lista
        Console.WriteLine(index);     // 1

        index = primes.IndexOf(10); // No existe en la lista
        Console.WriteLine(index); // -1
    }
}
NOTA. Cuando se utiliza IndexOf, siempre se debe comprobar -1 o se generara una excepcion. Tenga en cuenta que también puede usar LastIndexOf para realizar la búsqueda en el orden inverso.

Crear codigo HTML desde nuestro archivo de code behind

Algunas veces es necesario crear una salida en codigo HTML con informacion proveniente de nuestra base de datos. En ASP tradicional se tenia que embeber el codigo de la base de datos entre el codigo HTML (entre <%   %>).
En NET esto es mas facil, en el siguiente ejemplo usaremos la clase StringBuilder() para crear la cadena de HTML y con el control Literal lo desplegaremos en nuestra pagina.
  • Primero, arrastramos un control Panel desde nuestra barra de herramientas y le asignamos las propiedades de ID, CssClass, etc.
  • Luego, arrastramos un control Literal de la barra de herramientas y le asignamos la propiedad ID.
En modo de diseño nuestra pagina quedaria asi:

En nuetro code behind mandamos el strem de HTML de la siguiente manera:
//Instanciamos la clase StringBuilder para manipular nuestra cadena
StringBuilder MisArchivos = new StringBuilder();
//Luego construimos nuestra cadena con el metodo Append de la clase
MisArchivos.Append("<a href='" + ResolveUrl(dt.Rows[i][2].ToString())+ "'><img border='0' href='");
MisArchivos.Append(dt.Rows[i][2].ToString());
MisArchivos.Append("' src='" + ResolveUrl("~/images/" + dt.Rows[i][0].ToString()+ "'>"));
MisArchivos.Append(dt.Rows[i][1].ToString());
MisArchivos.Append("</img></a> ");
//Le asignamos la cadena construida con el StrinBuilder a la propiedad Text del control Literal
literal.Text = MisArchivos.ToString();

En este caso el dt es un objeto DataTable que trae las direcciones Url de archivos que hay que desplegar en la pagina.
Con esto se desplegaran los controles HTML dentro del panel de la siguiente manera:

Agregar una columna autonumerica a un DataTable

Para agregar una columna autonumerica a un DataTable es necesario crear un objeto DataTable y un objeto Column que tenga la propiedad AutoIncrement en true y luego mezclarlo con el DataTable que deseamos como en el siguiente ejemplo:

DataTable myDt = new DataTable();
DataColumn dc = new DataColumn();
dc.ColumnName = "#";
dc.DataType = typeof(int);
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.AutoIncrementStep = 1;

BoardCode bc = new BoardCode();
DataTable dt = bc.GetHoldersByBcID(int.Parse(this.TextBox1.Text));

myDt.Columns.Add(dc);

myDt.Merge(dt);

this.GridView1.DataSource = myDt;
this.GridView1.DataBind();



Asi, cuando la despleguemos en un DataGridView se mostrara en la primera columna con un contador de renglones.

formato a un campo de fecha de un gridview

En esta ocación vamos a mostrar como cambiar el formato a un campo de un gridview.
El unico detalle que se presenta es que deben ser agregados los campos uno a uno, es decir debe desactivar el "Auto-generate fields" y en la página cambiar a modo "Source" donde vera el gridview de la siguiente forma.
<asp:BoundField DataField="plan_sdate" DataFormatString="{0}" HeaderText="Date" />
Esto nos daria como resultado el formato "8/20/2008 12:00:00 AM"
Para cambiar el formato a fecha corta solo debe modificar el DataFormatString.
DataFormatString="{0:MM/dd/yyyy}"
Lo cual nos dara como resultado "8/20/2008 "
Nota: Tambien se puede usar para cambiar a otros tipos de formato.
Anexo algunos ejemplos.
Ahora ahondemos un poco más en DataFormatString, las siguientes letras son para formatos numéricos:
C -> Muestra los valores numéricos en formato de moneda.
D -> Muestra los valores numéricos en formato decimal.
E -> Muestra los valores numéricos en formato científico (exponencial).
F -> Muestra los valores numéricos en formato fijo.
G -> Muestra los valores numéricos en formato general.
N -> Muestra los valores numéricos en formato numérico.
X -> Muestra los valores numéricos en formato hexadecimal.

Tipos de Datos en .NET

Tipos de datos para .Net y sus alias en Visual Basic y C#


Class Library Name
Vb Name
C# Name
Contains




Byte
Byte
byte
Entero de 0 a 255.
Int16
Short
short
Entero de -32,768 a 32,767.
Int32
Integer
int
Entero de -2,147,483,648 a 2,147,483,647.
Int64
Long
long
Entero de -9.2e18 a 9.2e18
Single
Single
float
Punto flotante de simple precisión de aproximadamente -3.4e38 a 3.4e38.
Double
Double
double
Punto flotante de doble precisión de aproximadamente -1.8e308 a 1.8e308.
Decimal
Decimal
decimal
Numero fraccional de punto fijo de 128-bits que soporta encima de 28 dígitos significativos.
Char
Char
char
Un simple carácter de 16-bits
String
String
string
Serie de caracteres de longitud variable.
Boolean
Boolean
bool
Un valor de falso o verdadero.
DataTime
Date
--
Representa alguna fecha de Enero 1ero 12:00:00 AM del año 1  a Diciembre 31, 11:59:59 del año 9999.
TimeSpan
--
--
Representa un valor de tiempo, tanto en 3 segundos o 3 días.
Object
Object
object
La  ultima clase base de todos los tipos de NET. Puede contener algún dato de tipo objeto.

Colores en .NET

Existen 4 formas para definir un color en .NET
  • Usando un valor ARGB(alpha, red, green,blue):
    • ctrl.ForeColor = Color.FromARGB(255,0,255,0);
  • Usando un color .NET Predefinido:
    • ctrl.ForeColor = Color.Crimson;
  • Usando un nombre HTML:
    • ctrl.ForeColor=ColorTranslator.FromHTML("Blue");
  • Usando un valor Hexadecimal en el formato #<red><green><blue>:
    • <asp:TextBox Forecolor="#FF50FF" Text="Test" ID="txtTestColor" runat="server" />

NOTA: alpha representa la transparencia (255=opaco).

Eventos de los controles web

  • Click:
    • Button, ImageButton.
  • TextChanged:
    • TextBox (Se dispara solo cuando el usuario cambia el foco a otro control).
  • CheckChanged:
    • CheckBox, RadioButton.
  • SelectedIndexChanged:
    • DropDownList, ListBox, CheckBoxList, RadioButtonList.
NOTA: Para capturar estos eventos la propiedad AutoPostBack debe estar en true.

Desplegar un mensaje de estado en nuestra página web usando Master Pages

Frecuentemente deseamos ofrecer a nuestros usuarios retroalimentación cuando estos usan nuestras páginas. La forma más usual de hacer esto es usar la barra de estado del explorador Web. Pero como existen muchos eventos que pueden modificar este mensaje y que no estan bajo nuestro control, preferimos usar una caja de texto o una etiqueta en el Master Page de nuestra aplicación y la llamamos desde cualquier página de contenido.
La forma de hacer esto es:
  • Agregar la directiva MasterType para poder acceder a las propiedades de la página Maestra en las páginas en que queramos mostrar un mensaje de estado.
    • Ejemplo <%@ MasterType VirtualPath="~/lesslearn.master" %>
Con esto ya podremos usar esta barra de estado solo poniendo en la propiedad StatusMessage el texto que deseamos desplegar y llamando al método DisplayMessage() de nuestra página maestra.
Ejemplo:
   Master.StatusMessage = "Aqui estoy";
   Master.DisplayMessage();
Cuando necesitemos que el mensaje desaparezca solo llamamos al método HideStatusBar().

como agregar una columna a una DataSet

DataSet dsBom = new DataSet(); //ITEM, PART#, DESC, QTY
CreateDataSet cdsBom = new CreateDataSet();

DataColumn dcEqty = new DataColumn("Eqty");
dsBom.Tables[0].Columns.Add(dcEqty); //agregando la columna dcEqty

//SE LE AGREGA UN DATO A LA NUEVA COLUMNA EN ESTE CASO "1565" dsBom.Tables[0].Rows[0]["Eqty"] = 1565;

Formas de pasar datos entre páginas web

Existen diferentes formas de pasar datos entre formas en la web. Sabemos que el protocolo http no guarda el estado (stateless), asi que los datso deben ser guardados en alguna parte. A diferencia del ASP tradicional en ASP.NET existen diferentes vias para hacerlo:
  1. Query String.
  2. Cookies.
  3. Variables de sesión.
  4. Cross Page Posting.
  5. Submit Form.
  6. Server.Transfer o Server.Execute.
1.- QueryStrings: Para pasar el contenido de TextBox1.Text de WebForm1 a Webform2 en el evento click de Button1.
   Para enviarlo:
   protected void Button1_Click(object sender, EventArgs e)
                   {
                        Response.Redirect("WebForm2.aspx?id=" + TextBox1.Text);
                   }
   Para recibirlo:

   string queryStringID = Request.QueryString["id"];
2.- Cookies
Para guardar el valor de TextBox1.Text en una cookie:
   protected void Button1_Click(object sender, EventArgs e)
                            {
                               HttpCookie cookie = new HttpCookie("UserName");
                               cookie.Value = TextBox1.Text;
                               cookie.Expires = DateTime.Now.AddDays(1);
                               Response.Cookies.Add(cookie);
                               Response.Redirect("WebForm2.aspx");
                             }

Para leerla:

   if(Request.Cookies["UserName"] != null)
                             Response.Write(Request.Cookies["UserName"].Value);
3.- Variables de Sesión:

   Para poner el valor del TextBox1.Text en una variable de sesión:
      protected void Button1_Click(object sender, EventArgs e)
                                            {
                                                Session["UserName"] = TextBox1.Text;
                                                Response.Redirect("WebForm2.aspx");
                                            }
Para leerla:

       Response.Write(Session["UserName"]);
4.- Cross Page Posting:
Poner en la propiedad PostBackUrl del Button1 la dirección de la segunda página:
   Y en la segunda página podemos obtener el valor de la siguiente manera:
         TextBox txtFirstPage = (TextBox)(PreviousPage.FindControl("TextBox1"));
      Response.Write(String.Format("You wrote {0} in Page1",txtFirstPage.Text));

5.- Submit Form.

Esto funciona con controles HTML que no sean del lado del servidor.
Ejemplo de la primera página:
  <form id="Form1" method="post" runat="server">
     <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
  </form>
   <form name="SubmittedForm" action="WebForm2.aspx" method="post">
      <input id="Submit1" type="submit" value="submit" onclick="CopyTextToHiddenField()" />
      <input name="Hidden1" type="hidden" />
    </form>

La función CopyTextToHiddenField() copia el valor de la caja de texto a un campo escondido. Hay que ponerla dentro del tag <head> como en el siguiente ejemplo:
<script language="javascript">
            function CopyTextToHiddenField()
            {
                 var textbox1Value = document.getElementById("<%=TextBox1.ClientID%>").value;
                 document.forms[1].document.getElementById("Hidden1").value = textbox1Value;
            }
</script>

Ahora podemos obtener el valor de la siguiente manera:
   Response.Write(Request.Form["Hidden1"]);  
6.- Server.Transfer o Server.Execute:
En la página que tenemos nuestra forma debemos usar el Server.Transfer o Server Execute:
protected void Button1_Click1(object sender, EventArgs e)
 {  
    Server.Transfer("WebForm2.aspx", true);
  }


En la página en que queremos obtener los datos:

 Response.Write(Request.Form["TextBox1"]);

Estas son las formas que el sitio de Microsoft nos dice que podemos usar, pero hay una forma que a mi parecer es la mejor de las que he mostrado anteriormente (aunque no sea la ideal en todos los casos) y es la siguiente:
En la página inicial colocamos nuestros controles y los exponemos como propiedades:
 public partial class _Default : System.Web.UI.Page
{

     public TextBox pp_Nombre
    {
         get { return TextBox1; }
     }
     public TextBox pp_Telefono
     {
  get { return TextBox2; }
    
     }
     protected void Page_Load(object sender, EventArgs e)
     {

     }
 }

Y en la segunda página colocamos la siguiente directiva:
   <%@ PreviousPageType VirtualPath="~/Default.aspx"  %>
Después colocamos el siguiente código para leer los datos:
public partial class Default2 : System.Web.UI.Page
 {
     protected void Page_Load(object sender, EventArgs e)
     {
         Label1.Text = PreviousPage.pp_Nombre.Text;
         Label2.Text = PreviousPage.pp_Telefono.Text;

     }
 }


Como pueden ver en .NET existen varias formas de hacerlo y podemos escoger el que más se ajuste a nuestras necesidades.
NOTA:
Si estás usando Master Pages puedes usar Cross Page Posting, pero al buscar el control debes obtener primero una referencia al ContentPlaceHolder ya que es el contenedor de los controles de tu página aspx.
Ejemplo:
En la primera página pones en el control que vaya a llamar a la otra página el nombre de esta en la propiedad PostBackUrl.
y en la segunda accedes a los controles de la siguiente manera:
protected void Page_Load(object sender, EventArgs e)
   {
      if (Page.PreviousPage != null)
      {
         ContentPlaceHolder cph = (ContentPlaceHolder)Page.PreviousPage.Master.FindControl("LessonsLearnedPlaceHolder");
            if (cph != null)
            {
               TextBox Sourcelbl = (TextBox)cph.FindControl("txtfailureid");
               Component cmp = new Component();
               if (Sourcelbl != null)
               {
                  this.LblFailureid.Text = Sourcelbl.Text;
                  cmp.FailureID = LblFailureid.Text;
               }
            }
         }

      }
Y con esto tendremos acceso a las propiedades de todos los controles de la página previa.

Mover mensajes seleccionados a un personal folder en Oulook 2016

Este es un ejemplo de como mover los mensajes seleccionados a un personal folder (pst) en Outlook 2016 usando VBA. Sub MoveInbox()     Mov...