Задача такая: Имеется форма с двумя комбобоксами, отображающими список объектов одинакового типа (Person). На форме лежат два ObjectBinder компонента. Один для связывания списка комбобокса со списком объектов Person (один и тот же ObjectBinder используется как DataSource двух контролов), второй для связывания свойств рабочего объекта Marriage со значениями контролов на форме.
Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение. Мне кажется, что такое поведение ObjectBinder неверно. Не должен ObjectBinder, установленный как DataSource у ряда контролов, связывать также выбранные значения этих контролов.
Вот такой код:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using BLToolkit.ComponentModel;
using BLToolkit.EditableObjects;
namespace ObjectBinderTest
{
public class MarriageForm : Form
{
private ObjectBinder obWorkingObject;
private ObjectBinder obReferenceObject;
private Label lblHusband;
private Label lblWife;
private ComboBox cmbHusband;
private ComboBox cmbWife;
private IContainer components;
public MarriageForm()
{
InitializeComponent();
PersonList personList = new PersonList();
personList.Add(new Person(1, "Foo"));
personList.Add(new Person(2, "Bar"));
obReferenceObject.List = personList;
obWorkingObject.Object = new Marriage();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>protected override void Dispose( bool disposing )
{
if( disposing )
{
if (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.components = new System.ComponentModel.Container();
this.obWorkingObject = new BLToolkit.ComponentModel.ObjectBinder(this.components);
this.obReferenceObject = new BLToolkit.ComponentModel.ObjectBinder(this.components);
this.cmbHusband = new System.Windows.Forms.ComboBox();
this.cmbWife = new System.Windows.Forms.ComboBox();
this.lblHusband = new System.Windows.Forms.Label();
this.lblWife = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// obWorkingObject
// this.obWorkingObject.ItemType = typeof(ObjectBinderTest.Marriage);
//
// obReferenceObject
// this.obReferenceObject.ItemType = typeof(ObjectBinderTest.Person);
//
// cmbHusband
// this.cmbHusband.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.obWorkingObject, "HusbandId"));
this.cmbHusband.DataSource = this.obReferenceObject;
this.cmbHusband.DisplayMember = "Name";
this.cmbHusband.Location = new System.Drawing.Point(120, 56);
this.cmbHusband.Name = "cmbHusband";
this.cmbHusband.Size = new System.Drawing.Size(121, 21);
this.cmbHusband.TabIndex = 0;
this.cmbHusband.ValueMember = "Id";
//
// cmbWife
// this.cmbWife.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.obWorkingObject, "WifeId"));
this.cmbWife.DataSource = this.obReferenceObject;
this.cmbWife.DisplayMember = "Name";
this.cmbWife.Location = new System.Drawing.Point(120, 104);
this.cmbWife.Name = "cmbWife";
this.cmbWife.Size = new System.Drawing.Size(121, 21);
this.cmbWife.TabIndex = 1;
this.cmbWife.ValueMember = "Id";
//
// lblHusband
// this.lblHusband.Location = new System.Drawing.Point(16, 56);
this.lblHusband.Name = "lblHusband";
this.lblHusband.TabIndex = 2;
this.lblHusband.Text = "Husband";
//
// lblWife
// this.lblWife.Location = new System.Drawing.Point(16, 104);
this.lblWife.Name = "lblWife";
this.lblWife.TabIndex = 3;
this.lblWife.Text = "Wife";
//
// MarriageForm
// this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.lblWife);
this.Controls.Add(this.lblHusband);
this.Controls.Add(this.cmbWife);
this.Controls.Add(this.cmbHusband);
this.Name = "MarriageForm";
this.Text = "MarriageForm";
this.ResumeLayout(false);
}
#endregion/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new MarriageForm());
}
}
public class Person : EditableObject
{
public Person(){}
public Person(int id, string name)
{
Id = id;
Name = name;
}
public int Id;
public string Name;
}
public class PersonList : EditableArrayList
{
public PersonList()
: base(typeof(Person))
{}
public new Person this[int index]
{
get { return (Person)base[index]; }
set { base [index] = value; }
}
}
public class Marriage : EditableObject
{
public int HusbandId;
public int WifeId;
}
}
Здравствуйте, selfmade, Вы писали:
S>Задача такая: Имеется форма с двумя комбобоксами, отображающими список объектов одинакового типа (Person). На форме лежат два ObjectBinder компонента. Один для связывания списка комбобокса со списком объектов Person (один и тот же ObjectBinder используется как DataSource двух контролов), второй для связывания свойств рабочего объекта Marriage со значениями контролов на форме.
S>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение. Мне кажется, что такое поведение ObjectBinder неверно. Не должен ObjectBinder, установленный как DataSource у ряда контролов, связывать также выбранные значения этих контролов.
Работает так же как BindingSource в .NET 2.0. Если надо разные, то два варианта:
1.
Здравствуйте, selfmade, Вы писали:
S>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение.
Так работает CurrencyManager. Он один на источник коим является в данном случае obReferenceObject. Нужно делать два баиндера, но можно использовать один лист.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Дьяченко Александр, Вы писали:
ДА>Здравствуйте, selfmade, Вы писали:
S>>Задача такая: Имеется форма с двумя комбобоксами, отображающими список объектов одинакового типа (Person). На форме лежат два ObjectBinder компонента. Один для связывания списка комбобокса со списком объектов Person (один и тот же ObjectBinder используется как DataSource двух контролов), второй для связывания свойств рабочего объекта Marriage со значениями контролов на форме.
S>>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение. Мне кажется, что такое поведение ObjectBinder неверно. Не должен ObjectBinder, установленный как DataSource у ряда контролов, связывать также выбранные значения этих контролов.
ДА>Работает так же как BindingSource в .NET 2.0. Если надо разные, то два варианта: ДА>1.
ДА>
На какое свойство контрола Control1 источник связывания BindingSource1 привязывает данные?
В моём примере я хочу привязать одни и те же данные на свойство DataSource обоих контролов, при этом свойства SelectedValue в контролах связывать между собой мне не надо.
Здравствуйте, selfmade, Вы писали:
S>В моём примере я хочу привязать одни и те же данные на свойство DataSource обоих контролов, при этом свойства SelectedValue в контролах связывать между собой мне не надо.
Ложи на форму два баиндера и связывай их с одним листом.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, selfmade, Вы писали:
S>>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение.
IT>Так работает CurrencyManager. Он один на источник коим является в данном случае obReferenceObject. Нужно делать два баиндера, но можно использовать один лист.
Спасибо. Персональный байндер на контрол работает отлично.
Но вопрос единственного CurencyManager на один на источник остаётся. Это удобно, если хочется ходить по листу и отображать позицию в листе на множество контролов. Это неудобно, если хочется всего лишь иметь общий список и независимые позиции курсора в списке в каждом контроле.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, selfmade, Вы писали:
S>>В моём примере я хочу привязать одни и те же данные на свойство DataSource обоих контролов, при этом свойства SelectedValue в контролах связывать между собой мне не надо.
IT>Ложи на форму два баиндера и связывай их с одним листом.
Учитывая то, что таких контролов у меня будет много, я унаследовал от ComboBox и добавил ObjectBinder в новый контрол.
Здравствуйте, selfmade, Вы писали:
S>Но вопрос единственного CurencyManager на один на источник остаётся. Это удобно, если хочется ходить по листу и отображать позицию в листе на множество контролов. Это неудобно, если хочется всего лишь иметь общий список и независимые позиции курсора в списке в каждом контроле.
Межу списком и отдельными биндерами на каждый контрол надо сделать прослойку из еще одного биндера и список менят именно у него.