Обновление: я проверил ответ, прежде чем я полностью проверил, он все еще не работает.Я обновил приведенный ниже код, чтобы вы могли просто вставить его в пустой проект WinForms, и он должен скомпилироваться.
ОБНОВЛЕНИЕ: я обнаружил, что если я изменю выбранный элемент в ComboBox на любой другой элемент,теперь он ведет себя как ожидалось (в моем коде ниже я бы переключился с test1 на test2).Поскольку я еще не получил никаких ответов, я изменяю вопрос на этот.
Почему я должен перейти на другой элемент в поле со списком, прежде чем он покажет изменения, которые я делаю в базовом источнике данных?
Вот краткий тестовый пример того, что происходит.
- Измените
test1
на test1asdf
текст в txtBroken - нажмите, чтобы зафиксировать изменение
- текст в поле со списком не обновляется.
- Измените поле со списком на test2
- измените
test2
на test2asdf
текст в txtBroken - щелкните, чтобызафиксировать изменение
- текст в поле со списком немедленно показывает, что 'test2asdf' все еще отображает
test1
для первого элемента в раскрывающемся списке - изменить на
test1
- отображение поля со списком
test1
текстовое поле отображает test1asdf
- обновить текстовое поле для
test1asd
- поле со списком сразу отображает
test1asd
За исключением изменения за кадромвыбранный элемент при загрузке и его замена (это похоже на взлом) как я могу это исправить?
У меня есть поле со списком, привязанное к BindingSource
, привязанному к List<Holder>
, в качестве значения отображения которого Holder.Name
.У меня также есть текстовое поле, привязанное к Holder.Name
, но если я изменю текст в текстовом поле, это не изменит то, что отображается в поле со списком.Изменение выбранных элементов и возврат назад покажет обновленный текст в текстовом поле, но в поле со списком все еще будет отображаться старое значение.Как сделать элемент в обновлении поля со списком?
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Sandbox_Form
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
lstBroken = new BindingList<Holder>();
lstBroken.Add(new Holder("test1"));
lstBroken.Add(new Holder("test2"));
bsBroken = new BindingSource(lstBroken, null);
cmbBroken.DataSource = bsBroken;
cmbBroken.DisplayMember = "Name";
cmbBroken.SelectedIndex = 0;
txtBroken.DataBindings.Add("Text", bsBroken, "Name");
txtBroken.TextChanged += new EventHandler(txtBroken_TextChanged);
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
void txtBroken_TextChanged(object sender, EventArgs e)
{
((Control)sender).FindForm().Validate();
}
private BindingSource bsBroken;
private BindingList<Holder> lstBroken;
private ComboBox cmbBroken;
private TextBox txtBroken;
private Label label1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.cmbBroken = new System.Windows.Forms.ComboBox();
this.txtBroken = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// cmbBroken
//
this.cmbBroken.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbBroken.FormattingEnabled = true;
this.cmbBroken.Location = new System.Drawing.Point(12, 32);
this.cmbBroken.Name = "cmbBroken";
this.cmbBroken.Size = new System.Drawing.Size(94, 21);
this.cmbBroken.TabIndex = 0;
//
// txtBroken
//
this.txtBroken.Location = new System.Drawing.Point(13, 60);
this.txtBroken.Name = "txtBroken";
this.txtBroken.Size = new System.Drawing.Size(93, 20);
this.txtBroken.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(13, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(41, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Broken";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtBroken);
this.Controls.Add(this.cmbBroken);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private void cmbWorks_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
public class Holder
{
public Holder(string name)
{
Name = name;
}
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
}
}
}
}
Если я связываюсь с List<String>
вместо использования Holder.Name
, он работает, как и ожидалось (это всего лишь простой макет, настоящийкласс имеет больше, чем просто имя, поэтому список строк не будет работать).Я думаю, что это ключ к тому, что не так, но я не знаю, что это такое.Использование Observable вместо списка не имеет значения.