Usuário com melhor resposta
Databind datagrid e textbox

Pergunta
-
Pessoal,
tenho a seguinte situação.
uma tela com 2 textbox.....Nome e Email.
1 datagrid com apenas as colunas Nome e Id (sem a coluna Email mesmo).
1 classe Clientes
1 classe Cliente
preenchi com databind (pelo DataContext) o datagrid com a classe Clientes......
eu gostaria que ao selecionar um cliente no grid......a classe Cliente seja preenchida com este registro (procurado na classe Clientes no evento SelectionChanged do grid).......
e os campos textbox sejam preenchidos com os valores da classe Cliente preenchida acima (no SelecitionChanged) fazendo o DataBind........
alguém sabe como fazer isto ????
Abs,
Lucas Giustiquarta-feira, 13 de outubro de 2010 03:40
Respostas
-
Lucas,
Uma maneira é utilizar a classe CollectionViewSource e então não necessitar do código para tratar o evento SelectionChanged. Para isso, siga os seguintes passos (ou faça algo parecido).
1 - Defina um resource para a classe CollectionViewSource no XAML.
<UserControl.Resources>
<CollectionViewSource x:Key="cvs" />
</UserControl.Resources>
2 - Defina o resource como source para o binding do DataGrid e dos controles TextBox.
<sdk:DataGrid ItemsSource="{Binding}"
DataContext="{StaticResource cvs}"
AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding Id}"
Header="Id" />
<sdk:DataGridTextColumn Binding="{Binding Nome}"
Header="Nome" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<TextBox Text="{Binding Source={StaticResource cvs}, Path=Id, Mode=TwoWay}" />
<TextBox Text="{Binding Source={StaticResource cvs}, Path=Nome, Mode=TwoWay}" />
<TextBox Text="{Binding Source={StaticResource cvs}, Path=Email, Mode=TwoWay}" />
Obs: Nesse passo, se a sua classe Cliente implementa INotifyPropertyChanged, após o controle TextBox perder o foco o DataGrid é atualizado com o novo valor.
3 - No code-behind, defina a propriedade Source do CollectionViewSource com a sua coleção de clientes (que provavelmente é a sua classe Clientes).
// coleção de clientes
var colecaoDeClientes = new ObservableCollection<Cliente>
{
new Cliente { Id = 1, Nome = "Ari", Email = "ari@mail.com" },
new Cliente { Id = 2, Nome = "Bruno", Email = "bruno@mail.com" },
new Cliente { Id = 3, Nome = "Regiana", Email = "regiana@mail.com" },
};
// recupera CollectionViewSource dos resources
var collectionViewSource = (CollectionViewSource)this.Resources["cvs"];
// define source
collectionViewSource.Source = colecaoDeClientes;
Mais detalhes nos links abaixo:
CollectionViewSource Class
http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource(v=VS.95).aspxHow to: Bind to Hierarchical Data and Create a Master/Details View
http://msdn.microsoft.com/en-us/library/cc645060(v=VS.95).aspxEspero ter ajudado.
Att.
Ari C. Raimundo
MCAD, MCTS
http://araimundo.blogspot.com- Sugerido como Resposta Ari C. Raimundo terça-feira, 19 de outubro de 2010 03:08
- Marcado como Resposta Ari C. Raimundo quarta-feira, 27 de outubro de 2010 11:45
quinta-feira, 14 de outubro de 2010 02:07
Todas as Respostas
-
Lucas,
Uma maneira é utilizar a classe CollectionViewSource e então não necessitar do código para tratar o evento SelectionChanged. Para isso, siga os seguintes passos (ou faça algo parecido).
1 - Defina um resource para a classe CollectionViewSource no XAML.
<UserControl.Resources>
<CollectionViewSource x:Key="cvs" />
</UserControl.Resources>
2 - Defina o resource como source para o binding do DataGrid e dos controles TextBox.
<sdk:DataGrid ItemsSource="{Binding}"
DataContext="{StaticResource cvs}"
AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding Id}"
Header="Id" />
<sdk:DataGridTextColumn Binding="{Binding Nome}"
Header="Nome" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<TextBox Text="{Binding Source={StaticResource cvs}, Path=Id, Mode=TwoWay}" />
<TextBox Text="{Binding Source={StaticResource cvs}, Path=Nome, Mode=TwoWay}" />
<TextBox Text="{Binding Source={StaticResource cvs}, Path=Email, Mode=TwoWay}" />
Obs: Nesse passo, se a sua classe Cliente implementa INotifyPropertyChanged, após o controle TextBox perder o foco o DataGrid é atualizado com o novo valor.
3 - No code-behind, defina a propriedade Source do CollectionViewSource com a sua coleção de clientes (que provavelmente é a sua classe Clientes).
// coleção de clientes
var colecaoDeClientes = new ObservableCollection<Cliente>
{
new Cliente { Id = 1, Nome = "Ari", Email = "ari@mail.com" },
new Cliente { Id = 2, Nome = "Bruno", Email = "bruno@mail.com" },
new Cliente { Id = 3, Nome = "Regiana", Email = "regiana@mail.com" },
};
// recupera CollectionViewSource dos resources
var collectionViewSource = (CollectionViewSource)this.Resources["cvs"];
// define source
collectionViewSource.Source = colecaoDeClientes;
Mais detalhes nos links abaixo:
CollectionViewSource Class
http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource(v=VS.95).aspxHow to: Bind to Hierarchical Data and Create a Master/Details View
http://msdn.microsoft.com/en-us/library/cc645060(v=VS.95).aspxEspero ter ajudado.
Att.
Ari C. Raimundo
MCAD, MCTS
http://araimundo.blogspot.com- Sugerido como Resposta Ari C. Raimundo terça-feira, 19 de outubro de 2010 03:08
- Marcado como Resposta Ari C. Raimundo quarta-feira, 27 de outubro de 2010 11:45
quinta-feira, 14 de outubro de 2010 02:07 -
Boooaaa Ari.....
Valeu cara....
Abs,
Lucas Giustiquinta-feira, 14 de outubro de 2010 02:58 -
Ari,
No cenário acima.....
tem como utilizar um CollectionViewSource para o grid...e outro para os campos de detalhe ??
daí, quando um item do grid é selecionado.....este outro CollectionVewSource (cliente) é preenchido com o SelectedItem do grid......mas quando um campo de detalhe, por exemplo o campo nome for alterado, afetar a segunda CollectionViewSource (cliente) e não a primeira (Clientes "do grid")....
tem como ?
Lucas Giustisegunda-feira, 18 de outubro de 2010 15:38 -
Olá Lucas,
Na verdade a sua classe Cliente não é um CollectionViewSource.
Como eu comentei anteriormente:
...se a sua classe Cliente implementa INotifyPropertyChanged , após o controle TextBox perder o foco o DataGrid é atualizado com o novo valor.
Portanto, se a sua classe Cliente não implementar INotifyPropertyChanged (o que não acho legal) o seu DataGrid não apresentará automaticamente essa alteração. Mesmo assim, o seu CollectionViewSource ainda possui binding com a sua coleção de clientes que foi alterada.
Uma alternativa seria alterar o modo do binding dos controles TextBox para OneWay (ao invés de TwoWay) e então realizar a alteração do registro corrente em um botão Salvar. Por exemplo, no evento Click desse botão teríamos...
// recupera CollectionViewSource dos resources
var collectionViewSource = (CollectionViewSource )this .Resources["cvs" ];
// ICollectionView
var collectionView = collectionViewSource.View;
// registro corrente
var cliente = collectionView.CurrentItem as Cliente ;
if (cliente != null )
{
cliente.Nome = this .txtNome.Text;
cliente.Email = this .txtEmail.Text;
}
Espero ter ajudado.
Att.
Ari C. Raimundo
MCAD, MCTS
http://araimundo.blogspot.comterça-feira, 19 de outubro de 2010 03:00 -
Puts...entendi.....
se eu quero trabalhar com as classes separadamente (separando o Binding) tenho que não utilizar INotifyPropertyChanged, oq também não acho legal....
ou trabalhar realmente separado atribuindo cada um dos valores (textbox) à classe......
mas legal....pelo menos deu uma clareada sobre como trabalhar com Binding....
valeu cara....
Abs,
Lucas Giustiquarta-feira, 20 de outubro de 2010 01:50