英文:
C# How to compare List to itself after been changed? Equals doesn't work
问题
I have DataGrid bounded to List<Materials> through DataSource.
After editing values in the dataGrid, I want to get rows that have been modified, specifically where properties of Material changed.
For this, I wanted to compare the item from the DataGrid with the same item (by the ID property) from a static List bound to my DataGrid. I thought that it would be possible to do this comparison via Equals, but since my List<Materials> is a reference type and is bound to the DataGrid, all values in my primary list are changing too.
I tried to change the DataSource to a copy of this list or to an array, but in any case, the data in my source is modified.
object ok = item.DataBoundItem;
Materials m1 = ok as Materials;
Materials m2 = Materials.allofmaterials.Where(x => x.ID == m1.ID).First();
if (m1.Equals(m2)) // THIS DOESN'T WORK for me
{
//do my actions
}
How can I detect which rows have been modified and which properties have changed exactly?
I thought about dataGridView1.CellValueChanged, but I'm not sure about it. What if the user changed a value once and then changed it again to the original value? For the event, it will look like the value changed, but in general, the value will stay the same.
英文:
I have DataGrid bounded to List<Materials> through DataSource.
After editing values in dataGrid I want to get Rows, which have been modified. Where properties of Material changed.
For this I wanted to compare item from DataGrid with same item ( by ID property) from static List which is bound to my DataGrid. I thought that it would be possible to do by comparison via Equals, but as my List<Materials> is a reference type and it's bounded to DataGrid all values in my primary list changing too.
I tried to change DataSource to copy of this list, or to array but in any case data in my source is modified.
List<Materials> matList = Materials.allofmaterials;
dataGridView1.DataSource = matList;
//Materials[] array = new Materials[matList.Count];
//matList.CopyTo(array);
//dataGridView1.DataSource = array;
//List<Materials> newMateials = matList;
//dataGridView1.DataSource = newMateials;
object ok = item.DataBoundItem;
Materials m1 = ok as Materials;
Materials m2 = Materials.allofmaterials.Where(x => x.ID == m1.ID).First();
if( m1.Equals(m2)) // THIS DOESN'T WORK for me
{
//do my actions
}
How to detect what rows have been modified, and what properties exactly has changed?
I thought about dataGridView1.CellValueChanged but I'm not sure about it. Because what if user changed value once, and that changed it again to primary value. For the event it will looks like value changed, but generally value will stay the same.
答案1
得分: 1
以下是翻译好的部分:
- 制作一个列表的“深度”拷贝,用于比较。List<T>.CopyTo 创建一个“浅层”拷贝。要进行深度拷贝,使用
new
创建新的实例。 - 将
Materials
更改为值类型,即struct
或record struct
。使用值类型将避免深层拷贝与浅层拷贝的问题。 - 实现
Materials
的“脏”状态。当更改属性时,将IsDirty
属性设置为 true。检测更改的对象变为.Where(x => x.IsDirty)
。 - 如果预期
Materials
只是一个普通的数据对象,没有“智能”部分,可能需要一个包装器或适配器,其中包含一个Materials
实例并跟踪脏状态。
所有这些方法都有各自的权衡。
英文:
I don't know the full context and can't give a definitive answer but some different approaches that focus on the collection are:
- Make a 'deep' copy of the list for comparison. List<T>.CopyTo creates a 'shallow' copy. For a deep copy, create new instances with
new
. - Change
Materials
to be a value type, i.e. astruct
orrecord struct
. With a value type you won't have the deep copy versus shallow copy issue. - Implement a 'dirty' state for
Materials
. When a property is changed, set anIsDirty
property to true. Detecting the changed objects becomes.Where(x => x.IsDirty)
. - If
Materials
is expected to be just a plain old data object with no 'smarts', a wrapper or adapter that contains aMaterials
instance and tracks the dirty state may be needed.
All of these approaches have trade-offs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论