O evento SelectedIndexChanged é muito utilizado nos controles DropDownList, RadioButtonList, CheckBoxList e muitos outros controles ASP.NET. Este evento é disparado a cada vez que o usuário troca de opção nestes controles.

Nesta parte iremos criar duas tabelas de exemplo, inserir alguns registros em ambas as tabelas, de Estados e de Cidades, e criar uma aplicação adicionando dois DropDownLists.

Então crie duas tabelas no SQL Server, a de Estados e a de Cidades, a Listagem 01 nos mostra o script de criação das tabelas:

Listagem 1. Script de criação das tabelas Estado e Cidade

    CREATE TABLE Estado
    (
           IdEstado         INT IDENTITY(1,1) NOT NULL,
           Estado           VARCHAR(50)       NOT NULL,
           DataCadastro     DATETIME          NOT NULL,
           
           CONSTRAINT PK_IdEstado PRIMARY KEY (IdEstado)
    )
     
    CREATE TABLE Cidade
    (
           IdCidade         INT IDENTITY(1,1) NOT NULL,
           IdEstado         INT               NOT NULL,
           Cidade           VARCHAR(100)      NOT NULL,
           DataCadastro     DATETIME          NOT NULL,
           
           CONSTRAINT PK_IdCidade PRIMARY KEY (IdCidade),
           CONSTRAINT FK_Cidade_IdEstado FOREIGN KEY (IdEstado) REFERENCES Estado(IdEstado)
    )
             

Note que a tabela Cidade é relacionada com a tabela Estado.

Vemos na Listagem 02 o script para criação dos estados e das cidades fictícias, uma cidade para cada estado.

Listagem 2. Script de inserção dos registros nas tabelas criadas
 
            INSERT INTO Estado VALUES ('Amapá', GETDATE())
            INSERT INTO Estado VALUES ('Ceará', GETDATE())
            INSERT INTO Estado VALUES ('Espírito Santo', GETDATE())
            INSERT INTO Estado VALUES ('Goiás', GETDATE())
            INSERT INTO Estado VALUES ('Minas Gerais', GETDATE())
            INSERT INTO Estado VALUES ('Rio de Janeiro', GETDATE())
            INSERT INTO Estado VALUES ('Rio Grande do Sul', GETDATE())
            INSERT INTO Estado VALUES ('Santa Catarina', GETDATE())
            INSERT INTO Estado VALUES ('São Paulo', GETDATE())
            INSERT INTO Estado VALUES ('Tocantins', GETDATE())
             
            INSERT INTO Cidade VALUES (1, 'Cidade do Amapá', GETDATE())
            INSERT INTO Cidade VALUES (2, 'Cidade do Ceará', GETDATE())
            INSERT INTO Cidade VALUES (3, 'Cidade do Espírito Santo', GETDATE())
            INSERT INTO Cidade VALUES (4, 'Cidade de Goiás', GETDATE())
            INSERT INTO Cidade VALUES (5, 'Cidade de Minas Gerais', GETDATE())
            INSERT INTO Cidade VALUES (6, 'Cidade do Rio de Janeiro', GETDATE())
            INSERT INTO Cidade VALUES (7, 'Cidade do Rio Grande do Sul', GETDATE())
            INSERT INTO Cidade VALUES (8, 'Cidade de Santa Catarina', GETDATE())
            INSERT INTO Cidade VALUES (9, 'Cidade de São Paulo', GETDATE())
            INSERT INTO Cidade VALUES (10, 'Cidade de Tocantins', GETDATE())
            

Crie uma aplicação ASP.NET e nela inclua dois DropDownLists, como podemos ver na Listagem 03.

Listagem 3. ASPX da página com os dois DropDownLists
 
        <div>
        <h3>Evento SelectedIndexChanged</h3>
        <br />
        Estado:
        <br />
        <asp:DropDownList ID="ddlEstado" runat="server" />
        <br />
        <br />
        Cidade:
        <br />
        <asp:DropDownList ID="ddlCidade" runat="server" />
        <br />
    </div>
            

Abra o Server Explorer e adicione uma conexão com o database que você criou, que contenha as tabelas Estado e Cidade, criada na parte anterior. Aproveite e copie a string de conexão das Propriedades de sua conexão, para adicioná-la ao arquivo Web.Config, como pode ser visto na Listagem 04.

Listagem 4. String de Conexão adicionada ao Web.Config

        <connectionStrings>
        <add name="StringdeConexao" connectionString="Data Source=WELLINGTON-WIN\SQLEXPRESS;Initial Catalog=Artigos;Integrated Security=True"
             providerName="System.Data.SqlClient"/>
      </connectionStrings>
             

Agora crie um método que irá carregar os dados no 1º DropDownList, como pode ser visto na Listagem 05.

Listagem 5. Método para carregar os dados no DropDownList Estado
 
            private void CarregarDropDownListEstado()
            {
                string strInstrucao = "SELECT IdEstado, Estado FROM Estado"; 
                using (SqlConnection objConexao = new SqlConnection(ConfigurationManager.ConnectionStrings["StringdeConexao"].ConnectionString))
                {
                    using (SqlCommand objCommand = new SqlCommand(strInstrucao, objConexao))
                    {
                        objConexao.Open();
     
                        try
                        {
                            SqlDataReader objDataReader = objCommand.ExecuteReader(CommandBehavior.CloseConnection);
                            ddlEstado.DataSource = objDataReader;
                            ddlEstado.DataTextField = "Estado";
                            ddlEstado.DataValueField = "IdEstado";
                            ddlEstado.DataBind();
                            objDataReader.Close();
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(ex.Message);
                        } 
                        objConexao.Close();
                    }
                }
            }
            

Para que o código acima funcione sem erros é necessário que se declare os namespaces System.Data, System.Data.SqlClient e System.Configuration.

Chame o método no evento Page_Load da página, como é mostrado na Listagem 06.

Listagem 6. Chamada ao método criado no evento Page_Load

            if (!Page.IsPostBack)
            {
                        CarregarDropDownListEstado();
                  }
             

Assim o DropDownList só irá ser carregado da 1ª vez em que a página for executada. Veja o resultado na Figura 01.

DropDownList Estado
Figura 1. DropDownList Estado

Na aspx da página altere o DropDownList adicionando a ele a propriedade AutoPostBack e chamando o evento que usaremos neste artigo. A Listagem 07 nos mostra um exemplo disso:

Listagem 7. ASPX do DropDownList Estado

            <asp:DropDownList ID="ddlEstado" runat="server" AutoPostBack="true"
            OnSelectedIndexChanged="ddlEstado_SelectedIndexChanged" />
             

Agora na página de códigos, codifique o evento que acabamos de criar, como pode ser visto na Listagem 08.

Listagem 8. Evento SelectedIndexChanged

            protected void ddlEstado_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (!String.IsNullOrEmpty(ddlEstado.SelectedValue))
                {
                    CarregarDropDownListCidade(int.Parse(ddlEstado.SelectedValue));
                }
            }
             

Assim chamamos o método que irá carregar os dados do DropDownList de Cidades. A codificação dele pode ser vista na Listagem 09, note que ele é praticamente igual ao da Listagem 05, alterando apenas com a adição do IdEstado, que irá compor o Where da instrução SQL.

Listagem 9. Método para carregar os dados no DropDownList Cidade
 
        private void CarregarDropDownListCidade(int IdEstado)
            {
                string strInstrucao = "SELECT IdCidade, Cidade FROM Cidade WHERE IdEstado = @IdEstado";
                using (SqlConnection objConexao = new SqlConnection(ConfigurationManager.ConnectionStrings["StringdeConexao"].ConnectionString))
                {
                    using (SqlCommand objCommand = new SqlCommand(strInstrucao, objConexao))
                    {
                        if (IdEstado > 0)
                        {
                            objCommand.Parameters.AddWithValue("@IdEstado", IdEstado);
                            objConexao.Open();
                            try
                            {
                                SqlDataReader objDataReader = objCommand.ExecuteReader(CommandBehavior.CloseConnection);
                                ddlCidade.DataSource = objDataReader;
                                ddlCidade.DataTextField = "Cidade";
                                ddlCidade.DataValueField = "IdCidade";
                                ddlCidade.DataBind();
                                objDataReader.Close();
                            }
                            catch (Exception ex)
                            {
                                throw new Exception(ex.Message);
                            }
                            objConexao.Close();
                        }
                    }
                }
            }
            

Assim, cada vez que trocarmos de Estado, chamaremos o método acima, passando o Id do Estado para carregar a respectiva Cidade. Confira o resultado na Figura 02.

DropDownList Cidade, carregado de acordo com o Estado
Figura 2. DropDownList Cidade, carregado de acordo com o Estado