从另一个列表框添加后找不到 ValueMember
Does not find ValueMember after adding from another ListBox
有两个ListBox
。双击 lbSubject
元素,将此元素添加到第二个 lbSelectedSubject
。前提是 lbSelectedSubject
中不存在该元素。检查元素是否存在通过添加 ValueMember
的 List<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
包含 Display
和 Value
的正确项目和设置。 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 时。
有两个ListBox
。双击 lbSubject
元素,将此元素添加到第二个 lbSelectedSubject
。前提是 lbSelectedSubject
中不存在该元素。检查元素是否存在通过添加 ValueMember
的 List<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
包含 Display
和 Value
的正确项目和设置。 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 时。