gpt4 book ai didi

c# - 如何在 WinForms 中绑定(bind)多对多关系?

转载 作者:太空狗 更新时间:2023-10-29 23:20:05 26 4
gpt4 key购买 nike

我有以下数据集:

Products and Parts

ProductPart可以使用这些 DataGridViews 编辑表格:

Main Form

当用户双击产品网格中的一行时,将打开以下表单:

Product-Part Association

左栏应该列出与该产品相关的部件。右栏应该列出所有其他部分。使用 << 和 >> 按钮,用户应该能够选择哪些部分属于当前产品。

我已经用一对多关系做了类似的事情,而且效果很好。代码如下:

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 .我想使用某种查找来解决此问题,但我不知道如何解决。
  • 当您按下 << 时, 所选部分停留在右列而不是移动到左列。如果您尝试按 <<再次使用相同的部分,您会收到以下错误:

    System.Data.ConstraintException: 'Column 'ProductID, PartID' is constrained to be unique. Value '-4, -3' is already present.'

    (这是可以理解的)。我认为这可以使用过滤器表达式来解决,但我不确定如何编写它以及如何在每次更改后自动更新正确的列。

有没有人做过类似的事情,可以帮助我指明正确的方向?

最佳答案

这是我最终想到的。关键函数是 UpdateFilters,它创建分配给当前产品的零件 ID 列表,然后使用 INNOT 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;
}
}

关于c# - 如何在 WinForms 中绑定(bind)多对多关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50158476/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com