从另一个列表框添加后找不到 ValueMember

Does not find ValueMember after adding from another ListBox

有两个ListBox。双击 lbSubject 元素,将此元素添加到第二个 lbSelectedSubject。前提是 lbSelectedSubject 中不存在该元素。检查元素是否存在通过添加 ValueMemberList<int>

List<int> selectedValueSubject;

private void Form_Load(object sender, EventArgs e)
{
    selectedValueSubject = new List<int>();
    lbSelectedSubject.DisplayMember = "Title";
    lbSelectedSubject.ValueMember = "Id";

    lbSubject.DataSource = bindingSubjectDefault;
    lbSubject.DisplayMember = "Title";
    lbSubject.ValueMember = "Id";
}

private void LbSubject_MouseDoubleClick(object sender, MouseEventArgs e)
{
    int index = lbSubject.IndexFromPoint(e.Location);
    if (index != ListBox.NoMatches)
    {
        int id = (int)lbSubject.SelectedValue;
        if (IsNotConstrain(id, selectedValueSubject.ToArray()))
        {
            selectedValueSubject.Add(id);
            lbSelectedSubject.Items.Add(lbSubject.Items[index]);
        }
    }
}

private void LbSelectedSubject_MouseDoubleClick(object sender, MouseEventArgs e)
{
    int index = lbSelectedSubject.IndexFromPoint(e.Location);
    if (index != ListBox.NoMatches)
    {
        selectedValueSubject.Remove((int)lbSelectedSubject.SelectedValue);
        lbSelectedSubject.Items.RemoveAt(index);
    }
}

private bool IsNotConstrain(int id, int[] keys)
{
    bool result = true;
    foreach(int key in keys)
    {
        if (key == id)
        {
            result = false;
            break;
        }
    }

    return result;
}

添加正确。在这个人创建并显示 Title 的意义上。问题是相反的过程。从 lbSelectedSubject 中删除。 LbSelectedSubject_MouseDoubleClick 中的字符串抛出异常:

lbSelectedSubject.SelectedValue

System.NullReferenceException: "object Reference not pointing to object instance." System.Windows.Forms.ListControl.SelectedValue.get returned null.

lbSelectedSubject.Items 包含 DisplayValue 的正确项目和设置。 SelectedItem也正常,不为空。

列表 lbSubject 中的相同项目包含正确的值 Value,而不是 null

为什么在lbSelectedSubject中加入后通过行

lbSelectedSubject.Items.Add(lbSubject.Items[index]);

原来SelectedValue不行?其他同等条件下lbSubject.

UPDATE 它不是重复的。

如果 ListBox 没有数据源,则不能使用 SelectedValue 属性。
一个简单的解决方法是为第二个列表框提供一个与您为第一个列表框设置的类型相同的空数据源。

所以假设将您的第一个 ListBox 绑定到这种类型的 class

public class TitleData
{
    public int Id { get; set; }
    public string Title{ get; set; }
}

现在,当您构建第一个列表框数据源时,您也会构建第二个数据源

public void Form_Load(object sender, EventArgs e)
{
    selectedValueSubject = new List<int>();
    bsSelected.DataSource = new List<TitleData>();

    lbSelectedSubject.DisplayMember = "Title";
    lbSelectedSubject.ValueMember = "Id";
    lbSelectedSubject.DataSource = bsSelected; // <= this is a BindingSource at the class level
    .....

}

最后,在 MouseDoubleClick 事件中,您可以使用 SelectedItem 和 SelectedValue 引用您的数据

private void LbSelectedSubject_MouseDoubleClick(object sender, MouseEventArgs e)
{
    int index = lbSelectedSubject.IndexFromPoint(e.Location);
    if (index != ListBox.NoMatches)
    {
        // Always do this before removing the element from the BindingSource
        selectedValueSubject.Remove((int)lbSelectedSubject.SelectedValue);

        bsSelected.Remove(lbSelectedSubject.SelectedItem);
        // lbSelectedSubject.Items.RemoveAt(index);
    }
}

还有一个小问题。永远不要在设置数据源后设置 DisplayMember 和 ValueMember 属性。按此顺序执行将导致绑定发生两次,一次是在您设置数据源时,另一次是在您设置 ValueMember 时。