Llenar un DataGridView a partir de un SP (procedimiento almacenado) de una base de datos [Versión C#]

Problema: Me gustó la entrada anterior que explicaba cómo llenar un grid, pero ahora lo necesito en C#.
Solución: El nuevo ejemplo en C#

Para hacerlo un poco más real, ésta vez utilicé una base de datos existente y que Microsoft lo suele regalar como ejemplo.
La base de datos es pubs y el SP que escogí para este ejemplo es byroyalty.

Creé un formulario llamado Form1, el cual contiene un DataGridView llamado DataGridView1.

Luego, se escribe el procedimiento para llenar el grid.

private void Llenar_DataGridView()
{
    //Los argumentos de conexion a la base de datos
    string args="Data source=LAPTOP; Initial catalog=pubs; Integrated Security=SSPI";
    SqlConnection conn = new SqlConnection();
    conn.ConnectionString = args;

    try
    {
        //Indico el SP que voy a utilizar
        SqlCommand command = new SqlCommand("byroyalty", conn);
        command.CommandType = CommandType.StoredProcedure;
               
        SqlDataAdapter adapter = new SqlDataAdapter(command);

        //Envió los parámetros que necesito
        SqlParameter param = new SqlParameter("@percentage", SqlDbType.Int);
        param.Value = 100;
        command.Parameters.Add(param);

        DataTable dt = new DataTable();

        conn.Open();

        //Aquí ejecuto el SP y lo lleno en el DataTable
        adapter.Fill(dt);

        //Enlazo mis datos obtenidos en el DataTable con el grid
        dataGridView1.DataSource = dt;

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Este procedimiento lo llamo desde el load de la aplicación.
private void Form1_Load(object sender, EventArgs e)
{
    Llenar_DataGridView();
}

Listo, con esto queda explicado el mismo ejemplo que el anterior.

Si desean un video tutorial paso a paso, pueden utilizar el siguiente enlace.


Saludos a todos.

Configurar tamaño de papel - hoja personalizada en Crystal Report

Problema: Tengo un reporte creado en Crystal Report con un tamaño de papel personalizado, pero al momento de imprimir, sale con otro tamaño de hoja, por más que el reporte haya sido creado correctamente.
Solución: Por código, configurar el tamaño del papel.
La mayoría de la veces, cuando se crea un reporte, con un tamaño de hoja personalizado, éste se configura correctamente al momento de diseñarlo, pero existen ocasiones, en que por más que dibujemos todo a la perfección, en el rato de la verdad, la hoja toma otro tamaño, siendo imposible imprimir.
Hay que entender que Crystal Report toma la configuración de la impresora predeterminada al momento de mostrar un reporte o imprimirlo, pero algunas veces hace falta más que tener la impresora a punto para que el reporte funcione correctamente.
Aquí se deben tener en cuenta dos cosas: Primero, tener a la mano el nombre de la impresora; ésto es importante porque ya no vamos a usar la impresora predeterminada, se tiene que utilizar un nombre fijo, por lo que si no pueden saberlo por ustedes mismos, deben crear la opción en dónde se deberá obtener de alguna manera el nombre de la impresora. Segundo, tener también a la mano el nombre del papel personalizado; ésto debe ser más sencillo de obtener, puesto que bajo ese tipo de hoja fue creado el reporte, pero si no lo tienen, deberán obtenerlo de alguna manera.
Ahora viene el código.
Voy a utiliza un procedimiento genérico, en donde configuro el reporte.
Private Sub Configurar_Hoja_CrystalReport()
    'Se obtiene el informe a configurar            
    Dim rdInforme As New rptInforme

    'Obtener nombre de impresora
    Dim print_name As String = "Impresora"
    'Obtener nombre de hoja personalizada
    Dim print_paper As String = "HojaPersonalizada"

    'Opciones del Crystal Report
    Dim repOptions As CrystalDecisions.CrystalReports.Engine.PrintOptions
    'Se aplican al informe
    With rdInforme
 'Se obtienen la opciones de impresion
 repOptions = .PrintOptions
 'Se setean las opciones
 With repOptions
     'Obtiene el id del papel --> utiliza una función especial
     .PaperSize = GetPapersizeID(print_name, print_paper)
     'Señala la impresora a utilizar
     .PrinterName = print_name
 End With
    End With
End Sub

Para que funcione este procedimiento, se debe utilizar la siguiente función.
Public Function GetPapersizeID(ByVal PrinterName As String, ByVal PaperSizeName As String) As Integer
 Dim pdprint As New System.Drawing.Printing.PrintDocument()
        Dim PaperSizeID As Integer = 0
        Dim ppname As String = ""
        pdprint.PrinterSettings.PrinterName = PrinterName
        For i As Integer = 0 To pdprint.PrinterSettings.PaperSizes.Count - 1
            Dim rawKind As Integer
            ppname = PaperSizeName
            If pdprint.PrinterSettings.PaperSizes(i).PaperName = ppname Then
                rawKind = CInt(pdprint.PrinterSettings.PaperSizes(i).RawKind)
                PaperSizeID = rawKind
                Exit For
            End If
        Next
        Return PaperSizeID
End Function

De esta manera, el reporte funciona perfectamente.
Esta opción está probada en Visual Studio 2008 Professional

Limpiar todos los controles de un formulario

Problema: Tengo que "poner en blanco" o limpiar todos los controles que tengo dentro de mi formulario, pero sin mencionarlos uno por uno puesto que son muchos. El principal problema es que los controles a limpiar, por ejemplo unos TextBox, están dentro de contenedores como GroupBox o TabControl.
Solución: Encontré este código buscando por la red, lamentablemente no puedo ponerle autoría porque no puedo accesar a la página.
Se copia el siguiente procedimiento.
    Sub sub_limpiar_campos(ByVal c1 As Control)
        'Limpia todos los controles dentro del control principal (c1)
        'aunque esten dentro de otros controles
        For Each c As Control In c1.Controls
            If TypeOf c Is TextBox Then
                c.Text = "" ' eliminar el texto 
            Else
                sub_limpiar_campos(c)
            End If
            If TypeOf c Is ComboBox Then
                c.Text = "" ' eliminar el texto 
            Else
                sub_limpiar_campos(c)
            End If
            If TypeOf c Is DateTimePicker Then
                c.Text = Date.Today ' Pone la fecha actual 
            Else
                sub_limpiar_campos(c)
            End If
            If (TypeOf (c) Is CheckBox) Then
                CType(c, CheckBox).Checked = False 'Quita el check
            Else
                sub_limpiar_campos(c)
            End If
            If (TypeOf (c) Is RadioButton) Then
                CType(c, RadioButton).Checked = False 'Quita el check
            Else
                sub_limpiar_campos(c)
            End If
        Next
    End Sub

Se lo utiliza de la siguiente manera.
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click, Button2.Click
        'Para limpiar todos los controles dentro del formulario
        'Aunque estén dentro de un TabControl o GroupBox
        sub_limpiar_campos(Me)
    End Sub