ComboBox не будет обновлять свой список отображения, если вы сначала не измените выбор

Обновление: я проверил ответ до того, как полностью проверил, он все еще не работает. Я обновил приведенный ниже код, чтобы вы могли просто вставить его в пустой проект WinForms, и он должен скомпилироваться.

ОБНОВЛЕНИЕ: Я обнаружил, что если я изменю выбранный элемент в ComboBox на любой другой элемент, он теперь ведет себя как ожидалось (в моем коде ниже я бы переключился с test1 на test2). Поскольку я еще не получил никаких ответов, я изменяю вопрос на этот.

Почему я должен перейти на другой элемент в поле со списком, прежде чем он покажет изменения, которые я делаю в базовом источнике данных?

Вот краткий тестовый пример того, что происходит.

  1. Измените test1 на test1asdf текст в txtBroken
  2. нажмите, чтобы зафиксировать изменение
  3. текст в поле со списком делает не обновляется.
  4. Измените поле со списком на test2
  5. измените test2 на test2asdf текст в txtBroken
  6. щелкните для подтверждения изменения
  7. текст в поле со списком сразу показывает 'test2asdf' по-прежнему отображает test1 для первого элемента в раскрывающемся списке
  8. . Замените на . комбинированное окно test1
  9. отображает текстовое поле test1 отображает test1asdf
  10. update текстовое поле со списком test1asd
  11. немедленно отображает test1asd

За исключением закулисного изменения выбранного элемента при загрузке и его возврата обратно (это похоже на такой взлом), как я могу это исправить?


У меня есть поле со списком, связанное с BindingSource , привязанным к List , в качестве значения дисплея которого он имеет 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 вместо использования Holder.Name , он работает как положено (это всего лишь простой макет, реальный класс имеет больше, чем просто имя, поэтому список строк не будет работать). Я думаю, что это ключ к тому, что не так, но я не знаю, что это такое. Использование Observable вместо списка не имеет значения.

5
задан Ramzi Khahil 24 February 2017 в 09:54
поделиться