viernes, 10 de abril de 2015

C#. Tipos de datos

En C# los tipos de datos se pueden agrupar en dos tipos: tipos por valor y tipos por referencia.
Los tipos por valor son int, float, double, struct, enum, etc.
Los tipos por referencia son las clases, interfaces, delegados, arrays, etc.

A los tipos por valor no se les puede asignar el valor null. Sin embargo, estos tipos se pueden convertir en tipos anulables, que pueden representar todos los valores del tipo original y el valor null. Para convertir un tipo por valor en anulable sólo hay que añadir el símbolo ? después del tipo.

int? opcion = null;
...
if (opcion != null) Console.WriteLine("La opcion elegida es: {0}", opcion);
else Console.WriteLine("No se ha elegido una opcion");


El código anterior se puede simplificar considerablemente utilizando el operador ??. En el siguiente ejemplo a la cadena se le asigna el valor anterior al operador ?? si la variable opcion no tiene valor nulo, en caso contrario, se le asigna el valor que hay después de dicho operador.

String respuesta = "La opción elegida es: " + opcion.Value.toString() ?? "No se ha elegido una opción";
Console.WriteLine(respuesta);

martes, 7 de abril de 2015

Javascript: marca de agua

Una tarea muy común en el desarrollo de una página web es  la creación de controles de texto con una marca de agua. A continuación se muestra un ejemplo de esta tarea.

<html>
<head>
<script type="text/javascript">
    function establecerMarcaAgua() {
        var txtTexto = document.getElementById("txtTexto");
       
        if (txtTexto.value.length == 0) {
            txtTexto.value= "Introduzca el texto aquí";
            txtTexto.className = "marcaAgua";
        }
    }
    function quitarMarcaAgua() {
        var txtTexto = document.getElementById("txtTexto");
       
        if (txtTexto.value == "Introduzca el texto aquí") {
            txtTexto.value = "";
            txtTexto.className = "texto";
        }
    }
</script>
<style type="text/css">
    .marcaAgua {
        color: gray;
        font-weight: bold;
        font-size: 0.8em;
    }
    .texto {
        color: black;
        font-weight: normal;
        font-size: 1em;
    }
</style>
</head>

<body>
    Texto:
    <input type="text" id="txtTexto" value="Introduzca el texto aquí"
      class="marcaAgua"
      onfocus="quitarMarcaAgua()" onblur="establecerMarcaAgua()" />
</body>
</html>

A continuación se puede ver una versión genérica de las funciones anteriores que se pueden utilizar con múltiples controles.

<html>
<head>
<script type="text/javascript">
    function establecerMarcaAgua(texto, control) {      
        if (control.value.length == 0) {
            control.value= "Introduzca el texto aquí";
            control.className = "marcaAgua";
        }
    }
    function quitarMarcaAgua(texto, control) {      
        if (control.value == "Introduzca el texto aquí") {
            control.value = "";
            control.className = "texto";
        }
    }
</script>
<style type="text/css">
    .marcaAgua {
        color: gray;
        font-weight: bold;
        font-size: 0.8em;
    }
    .texto {
        color: black;
        font-weight: normal;
        font-size: 1em;
    }
</style>
</head>

<body>
    Texto:
    <input type="text" id="txtTexto" value="Introduzca el texto aquí"
        class="marcaAgua"
        onfocus='quitarMarcaAgua("Introduzca el texto aquí", this)'
        onblur='establecerMarcaAgua("Introduzca el texto aquí", this)' />
</body>
</html>

lunes, 6 de abril de 2015

ASP .NET: Procedimiento almacenado

En esta entrada se puede ver un ejemplo de uso de procedimientos almacenados en un método de una aplicación en ASP .NET.

private void Borrar(string IDs) {
  string cs = ConfigurationManager.ConnectionStrings["conStr"].ConnectionString;
  SqlConnection con = new SqlConnection(cs);
  SqlCommand cmd = new SqlCommand("spBorrarEmpleados", con);

  cmd.CommandType = CommandType.StoredProcedure;
  SqlParameter parameter = new SqlParameter("@IDs", IDs);
  cmd.Parameters.Add(parameter); con.Open(); 
  cmd.ExecuteNonQuery();

  con.Close(); }

viernes, 3 de abril de 2015

Android cheat sheet

Esta entrada está dedicada a anotar conceptos básicos para la programación en Android y que es necesario tener presentes en todo momento, ya sea en la memoria o en una entrada en un blog.

- Layouts:
  <FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"> </FrameLayout>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:padding="25dp"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:weightSum="100"  (peso total de las vistas contenidas)
      android:background="@drawable/imagen_background.png" >
  </LinearLayout>
  <TableLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
       <TableRow>
         <TextView android:text="celda 1.1" />
         <TextView android:text="celda 1.2" />
      </TableRow>
      <TableRow>
         <TextView android:text="celda 2.1" android:layout_span="2" />
        (ocupa dos columnas)
     </TableRow>
   </TableLayout>
   <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:rowCount="2"
     android:columnCount="3"
     android:orientation="horizontal" >
         <TextView android:text="celda 1.1" />
         <TextView android:text="celda 1.2" />
         <TextView android:text="celda 2.1"  android:layout_columnSpan="2" />
   </GridLayout>
  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent"
     android:layout_height="match_parent" >
      <EditText android:id="@+id/TxtNombre"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text" />
     <Button android:id="@+id/BtnAceptar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/TxtNombre"
        android:layout_alignParentRight="true" />
  </RelativeLayout>
- Controles(views):
  <Button
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:text="Pulsar"
    android:layout_gravity="center"
    android:weight="80"  (en realidad, ocupa el 20% del peso total)
    android:textSize="20dp"
    android:id="@+id/btnPulsar" />
  <ToggleButton android:layout_weight="20" android:text="ToggleButton"
    android:id="@+id/tbtn1" android:layout_width="match_parent"
    android:paddingBottom="10dp" android:checked="true"
    android:layout_height="wrap_content" />
  <EditText android:layout_width="match_parent" android:layout_height="wrap_content"
    android:id="@+id/etNombre" android:hint="Escribe el nombre"
    android:password="true" />
- Definir actividad en AndroidManifest.xml:
  <activity android:name=".Splash" android:label="@string/nombre">
    <intent-filter>
      <action android:name="android.intent.action.MAIN" /> (not.ebacelo.android.APP)
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  </activity>
- Button btnA = (Button) findViewById(R.id.btnA);
   TextView tvTexto = (TextView)findViewById(R.id.txtTexto);
   final EditText etEntrada= (EditText)findViewById(R.id.etEntrada);
   etEntrada.setInputType(InputType.TYPE_CLASS_TEXT |
     InputType.TYPE_TEXT_VARIATION_PASSWORD);
   tvTexto.setGravity(Gravity.CENTER);
- btnA.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
      Random rand = new Random();
      if (cadena.contentEquals("texto")
        txtTexto.setText("Texto para la vista");
        txtTexto.setTextColor(Color.BLUE);
        txtTexto.setTextSize(rand.nextInt(40);
    }
  }
  //Otra opción es implementar la interfaz View.OnClickListener y
  //el método onClick dentro de la clase correspondiente.
  //btnA.setOnClickListener(this)
- protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash);

    ourSong = MediaPlayer.create(Splash.this,  R.raw.sonido);
    ourSong.start();

    Thread timer = new Thread() {
       public void run() {
         try {
           sleep(5000);
         } catch (InterruptedException e) {
           e.printStackTrace();
         } finally {
           Intent openSplash = new Intent("not.ebacelo.android.SPLASH");
           startActivity(openSplash);
         }
       }
     }
  }
- protected void onPause() {
    super.onPause();
    ourSong.release();
    finish();
  }

- Lista de elementos:
  public class Menu extends ListActivity {
    String elementos[] = {"elemento1", "elemento2", "elemento3", "elemento4"};

    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setListAdapter(new ArrayAdapter<String>(Menu.this,
         android.R.layout.simple_list_item_1, elementos));
    }
    protected void onListItemClick(ListView l, View v, int position, long id) {
      super.onListItemClick(l, v, position, id);
      String elementoSeleccionado = elementos[position];
      try {
        Class miClase = Class.forName("not.ebacelo.android.splash");
        Intent miIntent = new Intent(Menu.this, miClase);
        startActivity(miIntent);
      } catch (ClassNotFounException e) {
        e.printStackTrace();
      }
    }
  }