none
Classe + DataGrid + Bnding RRS feed

  • Pergunta

  • Olá amigos.

    Estou carregando uma classe (bem simples, só com algumas propriedades públicas) a partir de um arquivo .csv

    Ciei uma List<classe> para armazenar as instâncias dessa classe já com suas respectivas propriedades inseridas.

    Agora preciso vincular meu datagrid a essa List e posteriormente, se eu fizer alterações nos valores de uma instancia dentro dessa list, o valor seja atualizado automaticamente no grid.

    Alguem poderia me dar um exemplo aqui mesmo de como fazer isso?


    Se a resposta foi útil, por favor marque como útil. Leia a bíblia.

    terça-feira, 16 de julho de 2013 12:42

Respostas

  • bom vamos lá

    Na sua Classe você vai ter que adicionar a interface INotifyPropertyChanged

      public class MinhaClasse : INotifyPropertyChanged
        {
            //Implementar a interface INotifyPropertyChanged conforme abaixo, você pode criar uma classe base
            //essa implementação vai notificar o grid qndo vc alterar as propriedades.
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string property) 
            {
                if (this.PropertyChanged != null) 
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(property));
                }
            }

            //Suas propriedades abaixo, usando o metodo que você criou para notificar

            private int _id;
            public int Id
            {
                get { return _id; }
                set 
                {
                    if (_id != value)
                    {
                        _id = value;
                        this.NotifyPropertyChanged("Id");
                    }
                }
            }

            private string _nome;
            public string Nome
            {
                get { return _nome; }
                set
                {
                    if (_nome != value)
                    {
                        _nome = value;
                        this.NotifyPropertyChanged("Nome");
                    }
                }
            }
        }

    Aqui está o XAML que desenvolvi como exemplo e para que você possa se basear

    <Window x:Class="laboratorioWPF.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="5*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <DataGrid x:Name="grd" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" ItemsSource="{Binding }">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Código" Binding="{Binding Path=Id}"/>
                    <DataGridTextColumn Header="Nome" Binding="{Binding Path=Nome}"/>
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Row="1" Width="100" Height="50" Content="Adicionar" Click="Button_Click"   />
            <Button Grid.Row="1" Grid.Column="2" Width="100" Height="50" Content="Alterar" Click="Button_Click_1"  />
        </Grid>
    </Window>

    Aqui está o code behind para que você tenha idéia de como fazer as alterações

     public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                //Usar o ObservableCollection quando vc vai adicionar e remover elementos e precisa que
                //notifique grid, se vc usar lista e remover ele não vai notificar na tela e não vai remover
                //o elemento que foi excluido ou adicionado na lista que está vinculada ao grid.
                ObservableCollection<MinhaClasse> collecao = new ObservableCollection<MinhaClasse>();
                collecao.Add(new MinhaClasse() { Id = 1, Nome = "Valor 1" });
                collecao.Add(new MinhaClasse() { Id = 2, Nome = "Valor 2" });

                DataContext = collecao;

            }

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                ((ObservableCollection<MinhaClasse>)this.DataContext).Add(new MinhaClasse() { Id = 3, Nome = "Valor 3" });
            }

            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                MinhaClasse mc = ((ObservableCollection<MinhaClasse>)this.DataContext).First();
                mc.Id = 4;
                mc.Nome = "Valor 4";
            }
        }

    Espero ter ajudado.

    • Sugerido como Resposta Cesar Mendes da Silva terça-feira, 16 de julho de 2013 13:57
    • Marcado como Resposta Tianodraco quarta-feira, 17 de julho de 2013 13:39
    terça-feira, 16 de julho de 2013 13:57
  • Vc tem que implementar a interface INotifyPropertyChanged na classe, quando vc altera a propriedade da classe e precisa mostrar essa mudança, obrigatóriamente vc precisa notificar usando a implementação da interface, se não o controle nunca saberá que você alterou, acredito que a informação que vc viu na internet está errada.
    • Marcado como Resposta Tianodraco sexta-feira, 19 de julho de 2013 17:28
    quarta-feira, 17 de julho de 2013 16:57

Todas as Respostas

  • bom vamos lá

    Na sua Classe você vai ter que adicionar a interface INotifyPropertyChanged

      public class MinhaClasse : INotifyPropertyChanged
        {
            //Implementar a interface INotifyPropertyChanged conforme abaixo, você pode criar uma classe base
            //essa implementação vai notificar o grid qndo vc alterar as propriedades.
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string property) 
            {
                if (this.PropertyChanged != null) 
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(property));
                }
            }

            //Suas propriedades abaixo, usando o metodo que você criou para notificar

            private int _id;
            public int Id
            {
                get { return _id; }
                set 
                {
                    if (_id != value)
                    {
                        _id = value;
                        this.NotifyPropertyChanged("Id");
                    }
                }
            }

            private string _nome;
            public string Nome
            {
                get { return _nome; }
                set
                {
                    if (_nome != value)
                    {
                        _nome = value;
                        this.NotifyPropertyChanged("Nome");
                    }
                }
            }
        }

    Aqui está o XAML que desenvolvi como exemplo e para que você possa se basear

    <Window x:Class="laboratorioWPF.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="5*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <DataGrid x:Name="grd" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" ItemsSource="{Binding }">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Código" Binding="{Binding Path=Id}"/>
                    <DataGridTextColumn Header="Nome" Binding="{Binding Path=Nome}"/>
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Row="1" Width="100" Height="50" Content="Adicionar" Click="Button_Click"   />
            <Button Grid.Row="1" Grid.Column="2" Width="100" Height="50" Content="Alterar" Click="Button_Click_1"  />
        </Grid>
    </Window>

    Aqui está o code behind para que você tenha idéia de como fazer as alterações

     public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                //Usar o ObservableCollection quando vc vai adicionar e remover elementos e precisa que
                //notifique grid, se vc usar lista e remover ele não vai notificar na tela e não vai remover
                //o elemento que foi excluido ou adicionado na lista que está vinculada ao grid.
                ObservableCollection<MinhaClasse> collecao = new ObservableCollection<MinhaClasse>();
                collecao.Add(new MinhaClasse() { Id = 1, Nome = "Valor 1" });
                collecao.Add(new MinhaClasse() { Id = 2, Nome = "Valor 2" });

                DataContext = collecao;

            }

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                ((ObservableCollection<MinhaClasse>)this.DataContext).Add(new MinhaClasse() { Id = 3, Nome = "Valor 3" });
            }

            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                MinhaClasse mc = ((ObservableCollection<MinhaClasse>)this.DataContext).First();
                mc.Id = 4;
                mc.Nome = "Valor 4";
            }
        }

    Espero ter ajudado.

    terça-feira, 16 de julho de 2013 13:56
  • bom vamos lá

    Na sua Classe você vai ter que adicionar a interface INotifyPropertyChanged

      public class MinhaClasse : INotifyPropertyChanged
        {
            //Implementar a interface INotifyPropertyChanged conforme abaixo, você pode criar uma classe base
            //essa implementação vai notificar o grid qndo vc alterar as propriedades.
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string property) 
            {
                if (this.PropertyChanged != null) 
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(property));
                }
            }

            //Suas propriedades abaixo, usando o metodo que você criou para notificar

            private int _id;
            public int Id
            {
                get { return _id; }
                set 
                {
                    if (_id != value)
                    {
                        _id = value;
                        this.NotifyPropertyChanged("Id");
                    }
                }
            }

            private string _nome;
            public string Nome
            {
                get { return _nome; }
                set
                {
                    if (_nome != value)
                    {
                        _nome = value;
                        this.NotifyPropertyChanged("Nome");
                    }
                }
            }
        }

    Aqui está o XAML que desenvolvi como exemplo e para que você possa se basear

    <Window x:Class="laboratorioWPF.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="5*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <DataGrid x:Name="grd" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" ItemsSource="{Binding }">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Código" Binding="{Binding Path=Id}"/>
                    <DataGridTextColumn Header="Nome" Binding="{Binding Path=Nome}"/>
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Row="1" Width="100" Height="50" Content="Adicionar" Click="Button_Click"   />
            <Button Grid.Row="1" Grid.Column="2" Width="100" Height="50" Content="Alterar" Click="Button_Click_1"  />
        </Grid>
    </Window>

    Aqui está o code behind para que você tenha idéia de como fazer as alterações

     public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                //Usar o ObservableCollection quando vc vai adicionar e remover elementos e precisa que
                //notifique grid, se vc usar lista e remover ele não vai notificar na tela e não vai remover
                //o elemento que foi excluido ou adicionado na lista que está vinculada ao grid.
                ObservableCollection<MinhaClasse> collecao = new ObservableCollection<MinhaClasse>();
                collecao.Add(new MinhaClasse() { Id = 1, Nome = "Valor 1" });
                collecao.Add(new MinhaClasse() { Id = 2, Nome = "Valor 2" });

                DataContext = collecao;

            }

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                ((ObservableCollection<MinhaClasse>)this.DataContext).Add(new MinhaClasse() { Id = 3, Nome = "Valor 3" });
            }

            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                MinhaClasse mc = ((ObservableCollection<MinhaClasse>)this.DataContext).First();
                mc.Id = 4;
                mc.Nome = "Valor 4";
            }
        }

    Espero ter ajudado.

    • Sugerido como Resposta Cesar Mendes da Silva terça-feira, 16 de julho de 2013 13:57
    • Marcado como Resposta Tianodraco quarta-feira, 17 de julho de 2013 13:39
    terça-feira, 16 de julho de 2013 13:57
  • Opa Cesar, obrigado por sua ajuda.

    Enanto implemento e testo seu código quero t perguntar sobre algo q li na web: muitos programadores falam em usar a classe ObservableCollection<T> já q ela implementa internamente o INotyfyPropertChange, não tendo necessidade do programador fazer na unha.

    Até o momento eu tenho o seguinte código:

    XAML:

    <Window x:Class="TesteObservableCollection.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="384.615" Width="707.051">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="233"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Button x:Name="btnAdiconnarPessoa" Content="Adicionar" HorizontalAlignment="Left" Margin="158,112,0,0" VerticalAlignment="Top" Width="75" Click="btnAdiconnarPessoa_Click"/>
            <TextBox x:Name="txtNome" Height="23" Margin="10,26,0,0" TextWrapping="Wrap" VerticalAlignment="Top"/>
            <TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Nome" VerticalAlignment="Top"/>
            <TextBlock HorizontalAlignment="Left" Margin="10,62,0,0" TextWrapping="Wrap" Text="Endereço" VerticalAlignment="Top"/>
            <TextBox x:Name="txtEndereco" HorizontalAlignment="Left" Height="23" Margin="10,78,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="223"/>
            <Button x:Name="btnRemoverPessoa" Content="Remover" HorizontalAlignment="Left" Margin="158,166,0,0" VerticalAlignment="Top" Width="75" Click="btnRemoverPessoa_Click"/>
            <Button x:Name="btnAlterar" Content="Alterar" HorizontalAlignment="Left" Margin="158,139,0,0" VerticalAlignment="Top" Width="75" Click="btnAlterar_Click"/>
            <DataGrid x:Name="dgPessoas" Grid.Column="1" Margin="10" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Nome" Binding="{Binding Nome}"/>
                    <DataGridTextColumn Header="Endereço" Binding="{Binding Endereco}"/>
                </DataGrid.Columns>
            </DataGrid>
    
        </Grid>
    </Window>

    Classe Pessoa:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace TesteObservableCollection
    {
        class Pessoa
        {
            public string Nome { get; set; }
            public string Endereco { get; set; }
        }
    }
    

    Code:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace TesteObservableCollection
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private ObservableCollection<Pessoa> ocPessoas;
            public MainWindow()
            {
                InitializeComponent();
    
                ocPessoas = new ObservableCollection<Pessoa>()
                { 
                    new Pessoa(){Nome = "Cristiano", Endereco="Rua Madalena Nunes 271"},
                    new Pessoa(){Nome = "D. Grace", Endereco="Rua Vereador Manoel Lira da Rocha 222"}
                };
                
                dgPessoas.ItemsSource = ocPessoas;
            }        
    
            private void btnAdiconnarPessoa_Click(object sender, RoutedEventArgs e)
            {
                ocPessoas.Add(new Pessoa(){Nome = txtNome.Text.Trim(), Endereco = txtEndereco.Text.Trim()});
                txtNome.Clear();
                txtEndereco.Clear();
            }
    
            private void btnRemoverPessoa_Click(object sender, RoutedEventArgs e)
            {
                if (dgPessoas.SelectedItem != null)
                    ocPessoas.RemoveAt(dgPessoas.SelectedIndex);
            }
    
            private void btnAlterar_Click(object sender, RoutedEventArgs e)
            {
                if (dgPessoas.SelectedItem != null)
                {
                    int itemSelecinado = dgPessoas.SelectedIndex;
                    ocPessoas[itemSelecinado].Nome = txtNome.Text.Trim();
                    ocPessoas[itemSelecinado].Endereco = txtEndereco.Text.Trim();
                }                
            }        
        }
    }
    

    A parte do botão alterar funciona pra modificar os valores a ObservableCollection, mas o grid não é atualizado... poderia me dar uma luz sobre isso?


    Se a resposta foi útil, por favor marque como útil. Leia a bíblia.

    quarta-feira, 17 de julho de 2013 11:38
  • Vc tem que implementar a interface INotifyPropertyChanged na classe, quando vc altera a propriedade da classe e precisa mostrar essa mudança, obrigatóriamente vc precisa notificar usando a implementação da interface, se não o controle nunca saberá que você alterou, acredito que a informação que vc viu na internet está errada.
    • Marcado como Resposta Tianodraco sexta-feira, 19 de julho de 2013 17:28
    quarta-feira, 17 de julho de 2013 16:57