C# Winforms - привязать текстовое поле к элементу массива из класса - PullRequest
0 голосов
/ 07 января 2020

В настоящее время я безуспешно пытаюсь связать элемент массива из класса с текстовым полем.

class Test{
   ...
   string[] toto = new string[]{"element1"};
}

Test test;
void form_load()
{
   test = new Test();
   textBox1.DataBinding.Add("Text", test, "toto(0)");
}

(я пытался, как описано здесь: Winforms Привязка данных к элементу в массиве )

Но я получаю:

System.ArgumentException: 'Cannot bind to the property or column Requires(0) on the DataSource. Parameter name: dataMember'

Если я свяжу это так:

checkBox2.DataBindings.Add(new Binding("Checked", config.Requires[0], ""));

Это работает, но я не могу реализовать INotifyPropertyChanged для обновления формы при внесении изменений, выполняемых кодом.

У кого-нибудь есть идеи?

Редактировать: после привязки форма должна обновляться, когда элемент массива обновляется.

Ответы [ 2 ]

0 голосов
/ 07 января 2020

Вполне возможно, есть лучший способ сделать это, но вы могли бы создать экземпляр BindingSource для каждого элемента в массиве, установить свойство BindingSource.Position, а затем установить его как привязку для TextBox.

Редактировать: Двухстороннее связывание данных ... изменение значения в элементе управления обновляет объект, изменение значения из объекта изменяет элемент управления.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Test
{
   public class Foo
   {
      public Foo()
      {
         Items = new BindingList<string>();
      }

      public IList<string> Items { get; private set; }
   }

   static class Program
   {
      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main()
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);

         _dataSource.Items.Add("Value");
         _dataSource.Items.Add("Value 2");
         _dataSource.Items.Add("Value 3");

         var frm = new Form();

         var flp = new FlowLayoutPanel
         {
            Dock = DockStyle.Fill,
            FlowDirection = FlowDirection.TopDown
         };

         for (int i = 0; i < _dataSource.Items.Count; i++)
         {
            var bs = new BindingSource(_dataSource, "Items");
            bs.Position = i;
            var tb = new TextBox();
            tb.DataBindings.Add("Text", bs, "");
            flp.Controls.Add(tb);
         }
         frm.Controls.Add(flp);

         var btn = new Button()
         {
            Text = "Show Object's Values",
            Dock = DockStyle.Bottom
         };
         btn.Click += btn_Click;
         frm.Controls.Add(btn);

         var btn2 = new Button()
         {
            Text = "Change Object's Values",
            Dock = DockStyle.Bottom
         };
         btn2.Click += btn2_Click;
         frm.Controls.Add(btn2);

         Application.Run(frm);
      }

      static void btn_Click(object sender, EventArgs e)
      {
         MessageBox.Show(string.Join(Environment.NewLine, _dataSource.Items.ToArray()));
      }

      static void btn2_Click(object sender, EventArgs e)
      {
         var rng = new Random();
         for (int i = 0; i < _dataSource.Items.Count; i++)
         {
            var b = new byte[8];
            rng.NextBytes(b);
            _dataSource.Items[i] = Convert.ToBase64String(b);
         }
      }

      static Foo _dataSource = new Foo();
   }
}
0 голосов
/ 07 января 2020

Вы можете создать свойство следующим образом:

private string _element1;
public string Element1
{
  get
  {
    return _element1;
  }
  set 
  {
   element1 = value;
    OnPropertyChanged(nameof(Element1));
  }
}

Установите его как: Element1 = config.Requires[0]; А затем используйте его для установки TextBox следующим образом: checkBox2.DataBindings.Add(new Binding("Checked", Element1, ""));

...