múltiplos actualização seleccionado INofityPropertyChange objetos em DataGridView
-
03-07-2019 - |
Pergunta
Eu estou trabalhando com um DataGridView
(Windows formas) com MultiSelect activado que é colocada em uma de Controlo de Utilizador. Eu gostaria de atualizar todas as linhas selecionadas de fora do User Control chamando um método público que implementa o seguinte código:
foreach(DataGridViewRow dr in dataGridView.SelectedRows)
{
MyBusiness business = (MyBusiness)dr.DataBoundItem;
business.Rating = 5;
}
Infelizmente, quando várias linhas são selecionados, apenas um DataGridViewRow
é imediatamente atualizada, ou seja, aquele que foi selecionado por último. Os objetos subjacentes são alterados e o NotifyPropertyChange-evento é acionado. Além disso, quando eu mudar a seleção após a atualização, vejo todas as linhas são atualizadas exatamente como eu gostaria que eles sejam imediatamente.
A segunda coisa, muito estranho: Quando eu definir um ponto de interrupção no Setter do Rating
-propriedade onde NotifyPropertyChange é demitido e esperar lá por alguns segundos antes de continuar a execução de código, tudo funciona bem (todas as linhas são imediatamente atualizados). Se eu não esperar, mas pressione F5 muito rapidamente cada vez que o ponto de interrupção é passado, eu recebo o efeito descrito acima.
Meu negócio objeto é assim (significativamente encurtadas, claro):
public class MyBusiness : INotifyPropertyChanged
{
private int _rating;
public int Rating
{
get { return _rating; }
set
{
if(_rating != value)
{
_rating = value;
NotifyPropertyChanged("Rating");
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
Alguém já notou este comportamento também, ou mesmo sabe uma solução (ou uma solução alternativa)?
Solução
Se o seu DGV está vinculado a uma lista regular, ele só subscreve o evento PropertyChanged para a linha atualmente selecionado. Tente usar um BindingList vez, ou chamar BindingSource.ResetItem (n) para cada item alterado.
MSDN dá um exemplo que usa um BindingList e também ( inutilmente) chama ResetItem. Jogar com o seu exemplo, e você pode ver que quer remover a chamada para ResetItem, ou substituir o BindingList com uma lista regualr <> irá funcionar como pretendido.