Carlos Mattos

May 2011 - Posts

WPF | Como implementar ListBoxItem com ContextMenu

Posted: Wed, May 11 2011 8:23 by Carlos Mattos | with no comments
Filed under: , , ,
WPF - Como Aplicar DropShadowEffect num ListBoxItem

Como todos sabem, o WPF oferece diversos recursos para aprimorarmos a interface das nossas aplicações. Todos os controles do tipo Lista podem ser customizados para exibir os dados desejados. Um efeito muito comum utilizado nestes controles é o DropShadowEffect que aplica uma “sombra” sobre o item selecionado na lista. A cor e a profundidade desta sombra são definidas através dos parâmetros Color e ShadowDepth respectivamente.

Construindo o exemplo

Para ilustrar esse recurso do WPF, vamos construir uma lista de amigos. Os itens da lista exibirão os nomes e imagens. O efeito DropShadowBitmapEffect será aplicado no evento MouseOver. Veja a aplicação de exemplo em tempo de execução.

Figura 1: ListBoxItem com DropShadowEffect aplicado

Para construir a interface apresentada na Figura 1, abra o Visual Studio, crie um novo projeto baseado no Template WPF Application. Na Janela MainWindow.xaml altere o código XAML de acordo com os quadros a seguir.

O primeiro passo é criarmos a seção <Grid.Resources>onde depositaremos o DataSource que será utilizado para alimentar o ListBox e o ListItemContainerStyle que contém as definições para aplicação do efeito visual nos itens da lista.

O primeiro grupo de código XAML que adicionaremos na seção Grid.Resources utiliza o XmlDataSource para criar uma lista de amigos contendo Nome e Imagem de cada item.

Figura 2: Código XAML para criar o XmlDataSource

O segundo grupo de código XAML na seção Grid.Resources cria o ControlTemplate para o ListBoxItem. Observe que o Template é definido dentro do Tag <Style>.  Este código define como os registros serão apresentados e utiliza um Trigger associado à propriedade IsMouseOver para aplicar o efeito DropShadowBitmapEffect. Confira o código na Figura 3.

 

Figura 3: Definindo o estilo para o controle ListBox

 Finalmente, vamos ao código necessário para implementar nosso controle ListBox. Observe que a propriedade ItemSource é alimentada através do StaticResource e a propriedade ItemContainerStyle estabelece o vínculo com o estilo RedDropShadowEffect definido na seção Grid.Resources. Confira o código na Figura 4.

Figura 4: O código do controle ListBox

O mesmo estilo pode ser melhorado acrescentando outro Trigger associado à propriedade IsSelected, definindo outra cor para o efeito visual. Este é apenas um exemplo dos recursos gráficos que estão disponíveis no WPF.

 

Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

 

Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.

Posted: Mon, May 9 2011 13:12 by Carlos Mattos | with no comments
Filed under: ,
SQL – Como excluir registros duplicados numa tabela sem chave primária.

Um cenário comum no dia-a-dia, quando lidamos com bancos de dados, é a necessidade de identificarmos e removermos registros duplicados numa tabela. A dificuldade aumenta quando não há chave-primária nesta tabela.

 

A seguir vou demonstrar três métodos que podem ser utilizados para esta finalidade.

 

Criando a Tabela de Exemplo

Para ilustrar os métodos que vou apresentar, precisamos criar uma tabela de exemplo. Abaixo está o código para criarmos esta tabela.

 

if exists (select * from sysobjects where name like '%Celebridades%')

      drop table Celebridades

go

 

create table Celebridades(

      PrimeiroNome nvarchar(25),

      Sobrenome nvarchar(25)

)

go

Quadro 1: Criando a tabela de exemplo

 

Uma vez definida a tabela, precisamos alimentá-la com os registros duplicados.

 

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Keeley','Hazell')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Stacy','Ferguson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Keeley','Hazell')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Cheryl','Cole')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Jennifer','Garner')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Scarlett','Johanson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Stacy','Ferguson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Katheryn','Winnick')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Stacy','Ferguson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('LeeLee','Sobieski')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Megan','Fox')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Arianny','Celeste')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Brittney','Palmer')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Keeley','Hazell')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Megan','Fox')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

Quadro 2: Alimentando a tabela de exemplo com registros duplicados

Você pode observar que em nossa tabela de exemplo alguns registros se repetem por duas, três e até quatro vezes. Agora vamos trabalhar na exclusão dos registros duplicados. Não podemos utilizar a declaração DELETE FROM para excluir os duplicados desta forma:

 

delete from Celebridades where PrimeiroNome = 'Minka' AND Sobrenome = 'Kelly'

 

Este comando excluiria todos os registros com o nome Minka Kelly, e este não é o resultado esperado. Acompanhe a seguir três alternativas diferentes para solucionar esta questão.

 

 

Método 1: Utilizando o SET ROWCOUNT

 

A sintaxe para a declaração SET ROWCOUNT é:

 

SET ROWCOUNT { numero | @var_numero }

 

SET ROWCOUNT limita o SQL Server a processar um número específico de registros. Desta forma, o processo é interrompido após atingir o número de registros informado no argumento. O valor padrão para ROWCOUNT é 0 (zero), o que não estabelece limite para o comando, retornando todos os registros que atendam a cláusula WHERE.

 

Depois de executar o comando ROWCOUNT para limitar os registros que serão retornados pelo SQL, você pode executar o mesmo comando informando 0 (zero) como parametro para desabilitar esta opção.

 

Vamos tomar como exemplo o nome 'Minka Kelly', 5 registros serão retornados.

 

select * from Celebridades where primeironome = 'Minka' and sobrenome = 'Kelly'

 

Neste caso, precisamos excluir 4 dos 5 registros repetidos. Para isto devemos utilizar o ROWCOUNT atribuindo valor 4 para o parametro requerido. Veja o comando a seguir:

 

set rowcount 4

 delete from Celebridades where PrimeiroNome = N'Minka' and Sobrenome = N'Kelly'

set rowcount 0

-- (4 row(s) affected)

 

Depois de executar o comando acima, utilizando a declaração SET ROWCOUNT, execute o comando select e observe o resultado. Os registros repetidos foram excluídos.

 

select PrimeiroNome, Sobrenome from Celebridades

 

Você também pode utilizar o comando SET ROWCOUNT para excluir todos os registros duplicados da tabela de exemplo. Para atingirmos este objetivo, é necessário implementar um CURSOR.

 

Atenção ao declarar o CURSOR para identificar os registros duplicados, você deve definir o parametro do ROWCOUNT igual ao total de registros duplicados - 1, para preservar o registro original que será mantido na base após a execução deste comando.

 

Preste atenção no comando SET ROWCOUNT incluído no corpo do CURSOR.

 

declare @RegistrosDuplicados int

declare @PrimeiroNome nvarchar(25)

declare @Sobrenome nvarchar(25)

 

declare cursorDuplicados cursor fast_forward for

select PrimeiroNome, Sobrenome, count(*) - 1

from Celebridades

group by PrimeiroNome, Sobrenome

having count(*) > 1

 

open cursorDuplicados

 

fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

 

while @@fetch_status = 0

 

begin

      set rowcount @RegistrosDuplicados

      delete from Celebridades where PrimeiroNome = @PrimeiroNome and Sobrenome = @Sobrenome

      set rowcount 0

      fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

end

 

close cursorDuplicados

deallocate cursorDuplicados

Quadro 3: Utilizando o ROWCOUNT  com CURSOR

 

Método 2: Utilizando TOP

 

Um segundo método que podemos usar para remover registros duplicados é a expressão TOP combinada com a declaração DELETE. Desde o SQL 2005, como uma evolução do T-SQL, a expressão TOP passou a aceitar uma variável onde antes, no SQL 2000, só era possível atribuir uma constante numérica. Com esta mudança, podemos utilizar a expressão TOP dentro de um CURSOR para excluir todos os registros duplicados de uma só vez.

 

Utilizando nossa tabela de exemplo, podemos construir um comando para excluir os registros duplicados com o nome 'Minka Kelly', como apresentado nas linhas a seguir.

 

delete top(4) from Celebridades

 where PrimeiroNome = 'Minka' and Sobrenome = 'Kelly'

 

Trabalhando na mesma linha de raciocínio, podemos construir um CURSOR utilizando a expressão TOP. Veja o código abaixo.

 

declare @RegistrosDuplicados int

declare @PrimeiroNome nvarchar(25)

declare @Sobrenome nvarchar(25)

 

declare cursorDuplicados cursor fast_forward for

select PrimeiroNome, Sobrenome, count(*) - 1

from Celebridades

group by PrimeiroNome, Sobrenome

having count(*) > 1

 

open cursorDuplicados

 

fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

 

while @@fetch_status = 0

 

begin

      delete top(@RegistrosDuplicados) from Celebridades where PrimeiroNome = @PrimeiroNome and Sobrenome = @Sobrenome

      fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

end

 

close cursorDuplicados

deallocate cursorDuplicados

Quadro 4: Construindo CURSOR com a expressão TOP

 

Considere utilizar o método 2, com a expressão TOP, ao invés de utilizar o ROWCOUNT. A declaração ROWCOUNT não afetará os comandos DELETE, INSERT e UPDATE nas próximas versões do SQL. Consulte o Books On Line para mais informações (http://msdn.microsoft.com/en-us/library/ms188774.aspx).

 

Método 3: Adicionar uma coluna IDENTITY

 

O terceiro método é adicionar uma coluna IDENTITY na nossa tabela de exemplo. Execute o comando a seguir

para adicionar a coluna IDENTITY.

 

alter table Celebridades add Codigo int identity(1,1)

 

Agora, com a coluna IDENTITY podemos utilizar o comando DELETE para excluir os registros duplicados. Veja o exemplo a seguir.

 

delete from Celebridades where Codigo in(24,17,12,4)

 

Com a coluna IDENTITY inserida na nossa tabela de exemplo, podemos utilizar o recurso CTE (Common Table Expression) para excluir os registros duplicados, ao invés de usarmos um CURSOR. As CTEs foram introduzidas como aprimoramento do T-SQL a partir da versão 2005. Desta forma, o código abaixo não funcionará se voce tentar executá-lo no SQL Server 2000.

 

with CTEDuplicados(PrimeiroNome, Sobrenome, Codigo)

as

(

select PrimeiroNome, Sobrenome, Min(Codigo) Codigo

from Celebridades

group by PrimeiroNome, Sobrenome

having count(*) > 1

)

delete from Celebridades

where Codigo in (

select Celebridades.Codigo

from Celebridades

inner join CTEDuplicados

on Celebridades.PrimeiroNome = CTEDuplicados.PrimeiroNome

and Celebridades.Sobrenome = CTEDuplicados.Sobrenome

and Celebridades.Codigo <> CTEDuplicados.Codigo

)

Quadro 5: Utilizando CTE para excluir os registros duplicados

 

Após excluir os registros duplicados utilizando a CTE, você pode remover a coluna IDENTITY da tabela de exemplo executando o comando a seguir:

 

alter table Celebridades drop column Codigo

 

Aprofunde seus conhecimentos sobre este tema visitando a comunidade SQL Server no DevBrasil.

 

Faça download deste arquivo no formato PDF e também do código T-SQL deste exemplo.

Posted: Sat, May 7 2011 20:53 by Carlos Mattos | with 2 comment(s)
Filed under: