Usuário com melhor resposta
Como excluir item de uma DataGrid ? (WPF)

Pergunta
-
Galera, boa tarde
Na verdade minha questão vai um pouco mais a fundo que apenas "excluir item da DataGrid"
=> DataGrid.Items.Remove(DataGrid.SelectedItem);
Estou utilizando o ItemsSource da minha DataGrid, e quando executo este comando acima, me vem a seguinte exceção:
"Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."
Entendi oque a exceção me diz, porém queria saber como excluir algo do ItemsSource, mesmo com ele estando em uso. Ou se há outra maneira de resolver este problema.
Grato desde já.
Respostas
-
Exclui direto da lista, ou seja, da origem do bind.
exemplo abaixo:
<Window
using Aplicacao;
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="LaboratorioWPF.MainWindow"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<StackPanel Orientation="Horizontal">
<DataGrid x:Name="dtgClientes" ItemsSource="{Binding .}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Path=Id}"></DataGridTextColumn>
<DataGridTextColumn Header="Nome" Binding="{Binding Path=Nome}"></DataGridTextColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Tag="{Binding Path=Id}" Click="Button_Click">
Deletar
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Window>
using Dominio;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
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 LaboratorioWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//Tem que ser observableCollection, pois notifica o controle que está adicionando ou removendo itens
public ObservableCollection<Cliente> MeusClientes { get; set; }
public MainWindow()
{
InitializeComponent();
MeusClientes = new ObservableCollection<Cliente>();
DataContext = MeusClientes;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Preenche a lista de clientes;
for (int i = 0; i < 10; i++)
{
MeusClientes.Add(new Cliente() { Id = i, Nome = string.Format("Nome{0}", i) });
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Obtem o id clicado no grid
int id = Convert.ToInt32(((Button)sender).Tag);
var cliente = MeusClientes.Where(c => c.Id.Equals(id)).FirstOrDefault();
if (cliente != null)
{
MeusClientes.Remove(cliente);
}
}
}
}
- Marcado como Resposta Renan Valentim sexta-feira, 11 de setembro de 2015 15:52
-
Cesar Mendes, esta foi a solução ! Muito obrigado ! :)
Segue meu código como ficou:
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Windows; using System.Linq; using System.Windows.Controls; using System.Windows.Input; namespace PROJETO_EXEMPLO { public partial class MyWindow : Window { List<itePedVenda> _itensPedido = new List<itePedVenda>(); //Crio meu ObservableCollection public ObservableCollection<itePedVenda> MeusProdutos { get; set; } public MyWindow(List<itePedVenda> itensPedido) { this.InitializeComponent(); //Publico a lista "itensPedido" recebida _itensPedido = itensPedido; // Instancio ObservableCollection MeusProdutos = new ObservableCollection<itePedVenda>(); // Seto o ObservableCollection no ItemsSource da DataGrid dgItensPed.ItemsSource = MeusProdutos; } private void Window_Loaded(object sender, RoutedEventArgs e) { this.DataContext = rolDeEntrega; //Populo ObservableCollection que está vinculado a DataGrid, e não o ItemsSource dela diretamente foreach (var item in _itensPedido) { MeusProdutos.Add(item); } txtOp.Focus(); } private void ExcluirItem(object sender, RoutedEventArgs e) { if (dgItensPed.SelectedItem == null) return; MessageBoxResult result; if (dgItensPed.SelectedItem != null) { result = MessageBox.Show("Confirma a exclusão do item " + ((itePedVenda)dgItensPed.SelectedItem).COD_PRO + " ?", "Exclusão", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Guid id = ((Guid)((Button)sender).Tag); var cliente = MeusProdutos.Where(c => c.CHAVE.Equals(id)).FirstOrDefault(); if (cliente != null) { MeusProdutos.Remove(cliente); } } } }
- Marcado como Resposta Renan Valentim sexta-feira, 11 de setembro de 2015 17:01
Todas as Respostas
-
Olá Renan,
acredito que o caminho mais rápido é remover o item de sua coleção e atribuir novamente ao controle ! Por ex :
dgvTeste.ItemsSource = colecao; dgvTeste.ItemsSource = null; //remove o item da colecao; //adiciona novamente dgvTeste.ItemsSource = colecao;
-
Exclui direto da lista, ou seja, da origem do bind.
exemplo abaixo:
<Window
using Aplicacao;
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="LaboratorioWPF.MainWindow"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<StackPanel Orientation="Horizontal">
<DataGrid x:Name="dtgClientes" ItemsSource="{Binding .}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Path=Id}"></DataGridTextColumn>
<DataGridTextColumn Header="Nome" Binding="{Binding Path=Nome}"></DataGridTextColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Tag="{Binding Path=Id}" Click="Button_Click">
Deletar
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Window>
using Dominio;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
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 LaboratorioWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//Tem que ser observableCollection, pois notifica o controle que está adicionando ou removendo itens
public ObservableCollection<Cliente> MeusClientes { get; set; }
public MainWindow()
{
InitializeComponent();
MeusClientes = new ObservableCollection<Cliente>();
DataContext = MeusClientes;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Preenche a lista de clientes;
for (int i = 0; i < 10; i++)
{
MeusClientes.Add(new Cliente() { Id = i, Nome = string.Format("Nome{0}", i) });
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Obtem o id clicado no grid
int id = Convert.ToInt32(((Button)sender).Tag);
var cliente = MeusClientes.Where(c => c.Id.Equals(id)).FirstOrDefault();
if (cliente != null)
{
MeusClientes.Remove(cliente);
}
}
}
}
- Marcado como Resposta Renan Valentim sexta-feira, 11 de setembro de 2015 15:52
-
-
Isto irá limpar meu ItemsSource
=> dgvTeste.ItemsSource = null;
Não quero fazer isso, e sim remover apenas um item avulso.
Então crie uma ObservableCollection e atribua veja exemplo :
-
Cesar Mendes, esta foi a solução ! Muito obrigado ! :)
Segue meu código como ficou:
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Windows; using System.Linq; using System.Windows.Controls; using System.Windows.Input; namespace PROJETO_EXEMPLO { public partial class MyWindow : Window { List<itePedVenda> _itensPedido = new List<itePedVenda>(); //Crio meu ObservableCollection public ObservableCollection<itePedVenda> MeusProdutos { get; set; } public MyWindow(List<itePedVenda> itensPedido) { this.InitializeComponent(); //Publico a lista "itensPedido" recebida _itensPedido = itensPedido; // Instancio ObservableCollection MeusProdutos = new ObservableCollection<itePedVenda>(); // Seto o ObservableCollection no ItemsSource da DataGrid dgItensPed.ItemsSource = MeusProdutos; } private void Window_Loaded(object sender, RoutedEventArgs e) { this.DataContext = rolDeEntrega; //Populo ObservableCollection que está vinculado a DataGrid, e não o ItemsSource dela diretamente foreach (var item in _itensPedido) { MeusProdutos.Add(item); } txtOp.Focus(); } private void ExcluirItem(object sender, RoutedEventArgs e) { if (dgItensPed.SelectedItem == null) return; MessageBoxResult result; if (dgItensPed.SelectedItem != null) { result = MessageBox.Show("Confirma a exclusão do item " + ((itePedVenda)dgItensPed.SelectedItem).COD_PRO + " ?", "Exclusão", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Guid id = ((Guid)((Button)sender).Tag); var cliente = MeusProdutos.Where(c => c.CHAVE.Equals(id)).FirstOrDefault(); if (cliente != null) { MeusProdutos.Remove(cliente); } } } }
- Marcado como Resposta Renan Valentim sexta-feira, 11 de setembro de 2015 17:01
-
Daniel Brito system, muito bom este post que você me indicou, vou ler mais a respeito de Observable Collection.
Obrigado ! õ/