Desenvolvimento - Silverlight
Trabalhando com enumerados
Este artigo descreve passo a passo como consumir tipos enumerados em um combobox.
por Djonatas TenfenOlá pessoal, o post hoje será um pouco mais técnico e voltado para solucionar um “problema” que você pode perder algum tempo “garimpando” a internet para resolver, então para facilitar a vida de vocês vou mostrar como trabalhar com Enumerados em um Binding de dados Silverlight.
Criando a aplicação
Crie um projeto Silverlight Application normal ( Visual Studio ( 2008 ou 2010 ) > File > New > Project > Silverlight Application ==> para facilitar coloque o nome do projeto como SilverlightApplication1) depois de criar o projeto crie uma nova classe no projeto Silverlight nomeie-a como Pessoa em seguida inclua o seguinte trecho de código:
public
enum TipoPessoa
{
Fisica = 0,
Juridica = 1
}
public class Pessoa : INotifyPropertyChanged
{
private string _nome;
public string Nome
{
get
{
return
_nome;
}
set
{
_nome =
value;
OnPropertyChanged("Nome");
}
}
private TipoPessoa
_tipoPessoa;
public TipoPessoa TipoPessoa
{
get { return _tipoPessoa; }
set
{
_tipoPessoa
= value;
OnPropertyChanged("TipoPessoa");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string
propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
A código é bem simples tem apenas um Enumerado e uma classe Pessoa que possui 2 propriedades Nome e TipoPessoa e contem uma implementação básica da interface INotifyPropertyChanged, até ai tudo bem.
Agora abra o arquivo MainPage.xaml e crie 2 linhas no grid LayoutRoot, inclua um data grid na linha 0 e um StackPanel contendo um TextBlock e um ComboBox na linha 1 conforme código abaixo:
<Grid
x:Name="LayoutRoot"
Background="White">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<sdk:DataGrid AutoGenerateColumns="False"
Height="150" HorizontalAlignment="Left"
Name="dataGrid1" VerticalAlignment="Top"
Width="327">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="Nome" Binding="{Binding
Nome}" />
<sdk:DataGridTextColumn Header="Tipo Pessoa"
Binding="{Binding TipoPessoa,}” />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<StackPanel Grid.Row="1"
Name="stackPanel1" Width="290" DataContext="{Binding
ElementName=dataGrid1, Path=SelectedItem}">
<TextBox Height="23"
HorizontalAlignment="Left" Name="textBox1"
VerticalAlignment="Top" Width="120" Text="{Binding
Nome}"
/>
<ComboBox
x:Name="cboTipoPessoa"
ItemsSource="{Binding TipoPessoa}" SelectedIndex="{Binding
TipoPessoa}”/>
</StackPanel>
</Grid>
* não esqueça de adicionar
o namespace do data grid ( xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" )
para facilitar arraste o DataGrid a partir da ToolBox.
Agora que temos nossa tela praticamente funcionando abra o arquivo MainPage.xamls.cs e crie uma lista de dados que será o nosso ItemsSource do DataGrid, verifique o código abaixo:
public MainPage()
{
InitializeComponent();
ListaPessoas = new ObservableCollection<Pessoa>();
ListaPessoas.Add(new Pessoa()
{ Nome = "Djonatas Tenfen", TipoPessoa = TipoPessoa.Fisica });
ListaPessoas.Add(new Pessoa() { Nome = "CodeTec
Solutions", TipoPessoa = TipoPessoa.Juridica });
ListaPessoas.Add(new Pessoa() { Nome = "Silverlight
Brasil", TipoPessoa = TipoPessoa.Juridica });
ListaPessoas.Add(new Pessoa() { Nome = "João da Silva
", TipoPessoa = TipoPessoa.Fisica });
dataGrid1.ItemsSource = ListaPessoas;
}
public ObservableCollection<Pessoa> ListaPessoas { get; set; }
Observe que criei uma Propriedade ObservableCollection<Pessoa> ( lembre-se de adicionar o using System.Collections.ObjectModel; ) que será a lista de dados para preencher o DataGrid da MainPage, no próprio construtor da classe eu criei a lista e inclui algumas pessoas do tipo Física Jurídicas, determinei a mesma como ItemsSource do DataGrid, agora vamos executar e ver o problema.
Problema
Observe que os valores do enumerado apareceram corretamente no DataGrid porém no ComboBox não…
Solução
Uma solução para isso será trabalhar com Converter, o que seria isso ? Como o próprio nome já diz serve para converter valores que são implementações da interface IValueConverter, vamos precisar converter um enumerado em uma lista de dados para que seja consumido pelo ComboBox veja a baixo a codificação dos converter:
Crie uma pasta na sua aplicação nome-a como Converter ( não é obrigatório mas é melhor manter uma organização dos tipos de códigos que estamos consumindo, melhor mesmo é criar um Silverlight Library de Helpers e Converters e consumir esta em projetos distintos ) e crie uma classe dentro da pasta e nomeie a classe como EnumToIntConverter.cs, em seguida inclua o seguinte trecho de código:
public class EnumToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object
parameter, System.Globalization.CultureInfo culture)
{
return (int)value;
}
public object ConvertBack(object value, Type
targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.Parse(targetType,
value.ToString(), true);
}
}
public class EnumToIEnumerableConverter : IValueConverter
{
private Dictionary<Type, List<object>> cache =
new Dictionary<Type, List<object>>();
public object Convert(object value, Type
targetType, object parameter, System.Globalization.CultureInfo culture)
{
var type = value.GetType();
if (!this.cache.ContainsKey(type))
{
var fields =
type.GetFields().Where(field => field.IsLiteral);
var values =
new List<object>();
foreach (var
field in fields)
{
DescriptionAttribute[] a =
(DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute),
false);
if (a != null && a.Length > 0)
values.Add(a[0].Description);
else
values.Add(field.GetValue(value));
}
this.cache[type] = values;
}
return
this.cache[type];
}
public object ConvertBack(object value, Type
targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Observe que tem 2 classes neste código EnumToIntConverter e EnumToIEnumerableConverter que servem para converter o Enumerado em uma lista de dados e converter o item selecionado da lista em um enumerado, o legal disso tudo é que ela pode ser usado para qualquer enumerado.
Resolvendo
Agora que já temos a solução do problema vamos implementar, abra o arquivo MainPage.xaml e inclua o seguinte namespace xmlns:local="clr-namespace:SilverlightApplication1.Converter" confira se o namespace confere com o namespace das classes EnumToIEnumerableConverter e EnumToIntConverter que criamos anteriormente, agora vamos adicionar um resource no XAML para que possamos consumi-las, logo após a declaração dos namespace ( cabeçalho do arquivo MainPage.xaml ) inclua o seguinte trecho de código:
<UserControl.Resources>
<ResourceDictionary>
<local:EnumToIEnumerableConverter
x:Key="EnumToIEnumerableConverter" />
<local:EnumToIntConverter
x:Key="EnumToIntConverter"
/>
</ResourceDictionary>
</UserControl.Resources>
Observe que estou consumindo o alias local que está apontando para o namespace SilverlightApplication1.Converter, indiquei uma chave para cada classe, agora vamos substituir o código XAML do ComboBox para que ele consuma esses Resources e consequentemente consuma o converter:
Substitua o código do ComboBox pelo seguinte código:
<ComboBox
x:Name="cboTipoPessoa"
ItemsSource="{Binding TipoPessoa, Mode=OneTime,
Converter={StaticResource EnumToIEnumerableConverter}}"
SelectedIndex="{Binding TipoPessoa, Mode=TwoWay, Converter={StaticResource
EnumToIntConverter}}" />
Observe que agora temos uma propriedade “nova” no Binding, o Converter que consome um Static Resource que é a chave para a classe Converter que irá converter o Enum em uma lista para setar no ItemsSource do ComboBox e irá converter o SelectedIndex em um enumerado para setar na propriedade da classe
Vejam o resultado :
O Código fonte deste artigo está disponível –> EnumSilverlight31082010.rar
Obrigado. Não deixem de comentar, se alguém tiver outra maneira de fazer a mesma coisa não deixe de compartilhar
- Comunicação Local no SilverlightSilverlight
- Gerando Gráficos com Silverlight, WCF e LINQSilverlight
- Usando o Scroll do mouse para dar Zoom em Imagens com Silverlight 4Silverlight
- Criando Protótipos com o SketchFlow Parte FinalSilverlight
- Criando Protótipos com o SketchFlow Parte 1Silverlight