从另一个ListBox添加后找不到ValueMember

时间:2019-06-23 15:17:31

标签: c# winforms exception listbox selectedvalue

有两个ListBox。双击lbSubject元素,将此元素添加到第二个lbSelectedSubject中。前提是该元素尚未在lbSelectedSubject中。通过添加List<int>的{​​{1}}来检查元素是否存在。

ValueMember

加法正确。从这个意义上说,人创建并显示了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
  

System.NullReferenceException:“对象引用未指向对象实例。”   System.Windows.Forms.ListControl.SelectedValue.get返回null。

lbSelectedSubject.SelectedValue 包含正确的项目和lbSelectedSubject.ItemsDisplay的设置。 Value也通常不为空。

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

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

введите сюда описание изображения

为什么在通过行添加null之后

lbSelectedSubject

原来,SelectedValue不起作用?在其他lbSelectedSubject.Items.Add(lbSubject.Items[index]); 相等的条件下。

更新,它不是重复的。

1 个答案:

答案 0 :(得分:1)

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

因此,假设您的第一个ListBox绑定到这种类型的类

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时发生的。