У меня есть Windows Forms ListBox
, привязанная к данным BindingList
бизнес-объектов.Отображаемое свойство ListBox представляет собой строку, представляющую имя бизнес-объекта.У меня есть TextBox
, который не привязан к данным для свойства name, но вместо этого заполняется при изменении выбранного индекса ListBox, а TextBox после проверки устанавливает свойство name бизнес-объекта, а затем использует BindingList.ResetItem
для уведомления *Связанный элемент управления 1005 * (ListBox) обновляется, когда текстовое значение TextBox изменяется пользователем.
Это прекрасно работает, если только изменение имени не является изменением регистра (то есть «имя» на «Имя "), в этом случае ListBox
не обновляется (оно по-прежнему говорит" имя ", хотя значением имени свойства базового бизнес-объекта является" Имя ").
Может кто-нибудь объяснитьпочему это происходит и что я должен делать вместо этого?Мой текущий обходной путь - использовать BindingList.ResetBindings
, который может работать для меня, но может быть неприемлемым для больших наборов данных.
Обновление от 27.09.2011: Добавлен простой пример кода, который воспроизводитпроблема для меня.Это использует INotifyPropertyChanged
и привязывает текстовое поле к списку привязок.На основе Как заставить ListBox обновить текст элемента?
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WinformsDataBindingListBoxTextBoxTest
{
public partial class Form1 : Form
{
private BindingList<Employee> _employees;
private ListBox lstEmployees;
private TextBox txtId;
private TextBox txtName;
private Button btnRemove;
public Form1()
{
InitializeComponent();
FlowLayoutPanel layout = new FlowLayoutPanel();
layout.Dock = DockStyle.Fill;
Controls.Add(layout);
lstEmployees = new ListBox();
layout.Controls.Add(lstEmployees);
txtId = new TextBox();
layout.Controls.Add(txtId);
txtName = new TextBox();
layout.Controls.Add(txtName);
btnRemove = new Button();
btnRemove.Click += btnRemove_Click;
btnRemove.Text = "Remove";
layout.Controls.Add(btnRemove);
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object sender, EventArgs e)
{
_employees = new BindingList<Employee>();
for (int i = 0; i < 10; i++)
{
_employees.Add(new Employee() { Id = i, Name = "Employee " + i.ToString() });
}
lstEmployees.DisplayMember = "Name";
lstEmployees.DataSource = _employees;
txtId.DataBindings.Add("Text", _employees, "Id");
txtName.DataBindings.Add("Text", _employees, "Name");
}
private void btnRemove_Click(object sender, EventArgs e)
{
Employee selectedEmployee = (Employee)lstEmployees.SelectedItem;
if (selectedEmployee != null)
{
_employees.Remove(selectedEmployee);
}
}
}
public class Employee : INotifyPropertyChanged
{
private string name;
private int id;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
public int Id
{
get { return id; }
set
{
id = value;
OnPropertyChanged("Id");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
}
Обновление от 28.09.2011: Кажется, что проблема внутренняя в ListBoxуправление, а именно то, как он решает (не) обновить элемент, если его строковое представление эквивалентно новому значению, игнорируя различия регистра.Насколько я могу судить, это жестко запрограммировано в элементе управления без возможности его переопределить.