C# 如何在WinForms中绑定多对多关系?
我有以下数据集: 可以使用以下DataGridView编辑C# 如何在WinForms中绑定多对多关系?,c#,winforms,data-binding,ado.net,dataset,C#,Winforms,Data Binding,Ado.net,Dataset,我有以下数据集: 可以使用以下DataGridView编辑产品和零件表: 当用户双击产品网格中的一行时,将打开以下表单: 左栏应列出与本产品相关的零件。右栏应该列出所有其他部分。使用>按钮,用户应该能够选择属于当前产品的零件 我做过类似的一对多关系,效果非常好。守则如下: public partial class ProductPartsForm : Form { private int _productID; private DataSet1 _data; pu
产品
和零件
表:
当用户双击产品网格中的一行时,将打开以下表单:
左栏应列出与本产品相关的零件。右栏应该列出所有其他部分。使用>按钮,用户应该能够选择属于当前产品的零件
我做过类似的一对多关系,效果非常好。守则如下:
public partial class ProductPartsForm : Form
{
private int _productID;
private DataSet1 _data;
public ProductPartsForm(DataSet1 data, DataRowView productRowView)
{
var productRow = (DataSet1.ProductRow)productRowView.Row;
_productID = productRow.ID;
_data = data;
InitializeComponent();
productBindingSource.DataSource = productRowView;
assignedPartBindingSource.DataSource = productBindingSource;
assignedPartBindingSource.DataMember = "FK_Product_Part";
assignedPartsListBox.DisplayMember = "Name";
unassignedPartBindingSource.DataSource = _data;
unassignedPartBindingSource.DataMember = "Part";
unassignedPartsListBox.DisplayMember = "Name";
unassignedPartBindingSource.Filter = $"isnull(ProductID, 0) = 0";
}
private void assignButton_Click(object sender, EventArgs e)
{
var partRowView = (DataRowView)unassignedPartBindingSource.Current;
var partRow = (DataSet1.PartRow)partRowView.Row;
var productRowView = (DataRowView)productBindingSource.Current;
var productRow = (DataSet1.ProductRow)productRowView.Row;
partRow.ProductRow = productRow;
UpdateUI();
}
private void unassignButton_Click(object sender, EventArgs e)
{
var partRowView = (DataRowView)assignedPartBindingSource.Current;
var partRow = (DataSet1.PartRow)partRowView.Row;
partRow.SetProductIDNull();
UpdateUI();
}
private void UpdateUI()
{
assignedPartsListBox.Refresh();
unassignedPartsListBox.Refresh();
assignButton.Enabled = unassignedPartsListBox.Items.Count > 0;
unassignButton.Enabled = assignedPartsListBox.Items.Count > 0;
}
}
在多对多关系中,有两件事我无法去工作:
- 左列不显示零件的名称。它应该显示小写字母,如右栏;相反,它显示字符串
。我想通过某种查找来解决这个问题,但我不知道如何解决System.Data.DataRowView
- 当你按下
按钮的点击事件处理程序,以及时,我终于想到了这一点。关键功能是
,它创建分配给当前产品的零件ID列表,然后使用UpdateFilters
和IN
运算符“手动”过滤两列NOT IN
public partial class ProductPartsForm : Form { private int _productID; private DataSet1 _data; public ProductPartsForm(DataSet1 data, DataRowView productRowView) { var productRow = (DataSet1.ProductRow)productRowView.Row; _productID = productRow.ID; _data = data; InitializeComponent(); productBindingSource.DataSource = productRowView; assignedPartBindingSource.DataSource = _data; assignedPartBindingSource.DataMember = "Part"; assignedPartsListBox.DisplayMember = "Name"; unassignedPartBindingSource.DataSource = _data; unassignedPartBindingSource.DataMember = "Part"; unassignedPartsListBox.DisplayMember = "Name"; } private void ProductPartsForm_Load(object sender, EventArgs e) { UpdateFilters(); UpdateUI(); } private void assignButton_Click(object sender, EventArgs e) { var partRowView = (DataRowView)unassignedPartBindingSource.Current; var partRow = (DataSet1.PartRow)partRowView.Row; var productRowView = (DataRowView)productBindingSource.Current; var productRow = (DataSet1.ProductRow)productRowView.Row; _data.ProductPart.AddProductPartRow(productRow, partRow); UpdateFilters(); UpdateUI(); } private void unassignButton_Click(object sender, EventArgs e) { var partRowView = (DataRowView)assignedPartBindingSource.Current; var partRow = (DataSet1.PartRow)partRowView.Row; var productPartRow = _data.ProductPart .Single(pp => pp.ProductID == _productID && pp.PartID == partRow.ID); _data.ProductPart.RemoveProductPartRow(productPartRow); UpdateFilters(); UpdateUI(); } private void UpdateFilters() { var assignedIds = _data.ProductPart .Where(pp => pp.ProductID == _productID) .Select(pp => pp.PartID.ToString()); if (assignedIds.Any()) { assignedPartBindingSource.Filter = $"ID IN ({string.Join(",", assignedIds)})"; unassignedPartBindingSource.Filter = $"ID NOT IN ({string.Join(",", assignedIds)})"; } else { assignedPartBindingSource.Filter = "FALSE"; unassignedPartBindingSource.RemoveFilter(); } } private void UpdateUI() { assignedPartsListBox.Refresh(); unassignedPartsListBox.Refresh(); assignButton.Enabled = unassignedPartsListBox.Items.Count > 0; unassignButton.Enabled = assignedPartsListBox.Items.Count > 0; } }
如果您可以发布单独的问题,而不是将您的问题合并为一个问题,这是首选。这样,它可以帮助人们回答你的问题,也可以帮助其他人寻找至少一个你的问题。谢谢我不知道如何把它分解。我有点希望能有某种教科书上的方法来解决整个问题;类似于UI的主细节样式,但适用于多对多关系,而不是一对多关系。我会尽量缩小范围。好吧,你至少应该用这个问题来显示
引用的表。“我试图重新表述这个问题。新问题在这里。”,请不要问重复的问题!删除副本并使用副本信息编辑此问题productBindingSource