为同一个数据网格视图使用多个数据源
Use multiple datasources for the same datagridview
我有一个表单,其中包含两个代表系列的按钮、一个复制按钮、一个粘贴按钮和一个数据网格视图。
datagridView 通过单击家庭按钮接收家庭成员的对象列表作为数据源。
我的问题是:
将数据从一个家庭复制并粘贴到另一个家庭后,如果我从一个家庭的 datagridview 编辑一个单元格,所做的更改会自动应用于另一个家庭的同一对象。我不明白为什么以及我做错了什么。
有人可以帮助我吗?
这是我的代码:
private void BtnCopy_Click(object sender, EventArgs e)
{
List<Familymember> selectedFamilyMemberList = ((BindingList<Familymember>)dgvFamilyMember.DataSource).ToList();
if (selectedFamilyMemberList != null && selectedFamilyMemberList .Count > 0)
{
CopiedFamilyMemberList.AddRange(selectedFamilyMemberList);
btnPaste.Enabled = true;
}
}
private void BtnPaste_Click(object sender, EventArgs e)
{
ID_FamilyPasteTo = seletedFamily.ID;
Family[FamilyList.Find(x => x.ID == ID_FamilyPasteTo)].Clear();
if (CopiedFamilyMemberList.Count > 0 && ID_FamilyCopyFrom != ID_FamilyPasteTo )
{
Family[seletedFamily].AddRange(CopiedFamilyMemberList);
dgvDosingPart.DataSource = null;
dgvDosingPart.AutoGenerateColumns = false;
dgvDosingPart.DataSource = new BindingList<FamilyMember>(Family[seletedFamily]);
dgvDosingPart.Refresh();
btnPaste.Enabled = false;
}
CopiedFamilyMemberList.Clear();
}
尝试创建一个新列表:
List<Familymember> selectedFamilyMemberList = new List<Familymember>(((BindingList<Familymember>)dgvFamilyMember.DataSource).ToList());
听起来你只是在复制引用而不是值。您必须将该对象克隆到另一个列表。我使用的最简单的解决方案是 serialize/deserialize 到 json 或 XML 并在列表中有一个带有新引用的全新对象。
public T Clone(T obj)
{
JsonSerializerSettings jss = new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Formatting = Formatting.Indented
};
var json = JsonConvert.SerializeObject(obj, jss);
return JsonConvert.DeserializeObject<T>(json);
}
当您将克隆的对象放入列表并进行编辑时,您应该编辑此对象而不是源列表中的对象。
谢谢这个提示。它帮助我解决了问题。
我刚刚使 class FamilyMember 可克隆,向其添加了方法 Clone() 并再次实现了事件 BtnCopy_Click。
public class FamilyMember: ICloneable
{
public string Name { get; set; }
...
public virtual object Clone()
{
return (FamilyMember) this.MemberwiseClone();
}
}
private void BtnCopy_Click(object sender, EventArgs e)
{
List<Familymember> selectedFamilyMemberList = ((BindingList<Familymember>)dgvFamilyMember.DataSource).ToList();
if (selectedFamilyMemberList != null && selectedFamilyMemberList .Count > 0)
{
foreach (FamilyMember item in selectedFamilyMemberList)
{
CopiedFamilyMemberList.Add((FamilyMember)item.Clone());
}
btnPaste.Enabled = true;
}
}
我有一个表单,其中包含两个代表系列的按钮、一个复制按钮、一个粘贴按钮和一个数据网格视图。 datagridView 通过单击家庭按钮接收家庭成员的对象列表作为数据源。 我的问题是: 将数据从一个家庭复制并粘贴到另一个家庭后,如果我从一个家庭的 datagridview 编辑一个单元格,所做的更改会自动应用于另一个家庭的同一对象。我不明白为什么以及我做错了什么。
有人可以帮助我吗?
这是我的代码:
private void BtnCopy_Click(object sender, EventArgs e)
{
List<Familymember> selectedFamilyMemberList = ((BindingList<Familymember>)dgvFamilyMember.DataSource).ToList();
if (selectedFamilyMemberList != null && selectedFamilyMemberList .Count > 0)
{
CopiedFamilyMemberList.AddRange(selectedFamilyMemberList);
btnPaste.Enabled = true;
}
}
private void BtnPaste_Click(object sender, EventArgs e)
{
ID_FamilyPasteTo = seletedFamily.ID;
Family[FamilyList.Find(x => x.ID == ID_FamilyPasteTo)].Clear();
if (CopiedFamilyMemberList.Count > 0 && ID_FamilyCopyFrom != ID_FamilyPasteTo )
{
Family[seletedFamily].AddRange(CopiedFamilyMemberList);
dgvDosingPart.DataSource = null;
dgvDosingPart.AutoGenerateColumns = false;
dgvDosingPart.DataSource = new BindingList<FamilyMember>(Family[seletedFamily]);
dgvDosingPart.Refresh();
btnPaste.Enabled = false;
}
CopiedFamilyMemberList.Clear();
}
尝试创建一个新列表:
List<Familymember> selectedFamilyMemberList = new List<Familymember>(((BindingList<Familymember>)dgvFamilyMember.DataSource).ToList());
听起来你只是在复制引用而不是值。您必须将该对象克隆到另一个列表。我使用的最简单的解决方案是 serialize/deserialize 到 json 或 XML 并在列表中有一个带有新引用的全新对象。
public T Clone(T obj)
{
JsonSerializerSettings jss = new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Formatting = Formatting.Indented
};
var json = JsonConvert.SerializeObject(obj, jss);
return JsonConvert.DeserializeObject<T>(json);
}
当您将克隆的对象放入列表并进行编辑时,您应该编辑此对象而不是源列表中的对象。
谢谢这个提示。它帮助我解决了问题。 我刚刚使 class FamilyMember 可克隆,向其添加了方法 Clone() 并再次实现了事件 BtnCopy_Click。
public class FamilyMember: ICloneable
{
public string Name { get; set; }
...
public virtual object Clone()
{
return (FamilyMember) this.MemberwiseClone();
}
}
private void BtnCopy_Click(object sender, EventArgs e)
{
List<Familymember> selectedFamilyMemberList = ((BindingList<Familymember>)dgvFamilyMember.DataSource).ToList();
if (selectedFamilyMemberList != null && selectedFamilyMemberList .Count > 0)
{
foreach (FamilyMember item in selectedFamilyMemberList)
{
CopiedFamilyMemberList.Add((FamilyMember)item.Clone());
}
btnPaste.Enabled = true;
}
}