ObjectBinder связывает излишние свойства
От: selfmade США about:blank
Дата: 02.03.06 04:52
Оценка:
Задача такая: Имеется форма с двумя комбобоксами, отображающими список объектов одинакового типа (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.
Re: ObjectBinder связывает излишние свойства
От: Дьяченко Александр Россия  
Дата: 02.03.06 05:31
Оценка: 2 (1)
Здравствуйте, selfmade, Вы писали:

S>Задача такая: Имеется форма с двумя комбобоксами, отображающими список объектов одинакового типа (Person). На форме лежат два ObjectBinder компонента. Один для связывания списка комбобокса со списком объектов Person (один и тот же ObjectBinder используется как DataSource двух контролов), второй для связывания свойств рабочего объекта Marriage со значениями контролов на форме.


S>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение. Мне кажется, что такое поведение ObjectBinder неверно. Не должен ObjectBinder, установленный как DataSource у ряда контролов, связывать также выбранные значения этих контролов.


Работает так же как BindingSource в .NET 2.0. Если надо разные, то два варианта:
1.

         -> BindingSource1 -> Control1
        /
Данные <
        \
         -> BindingSource2 -> Control2

2.

                           -> BindingSource1 -> Control1
                          /
Данные -> BindingSource0 <
                          \
                           -> BindingSource2 -> Control2

Потому что Position определен на уровне BindingSource и он один для всех. Для ObjectBinder должно быть так же.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: ObjectBinder связывает излишние свойства
От: IT Россия linq2db.com
Дата: 02.03.06 05:35
Оценка: 2 (1)
Здравствуйте, selfmade, Вы писали:

S>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение.


Так работает CurrencyManager. Он один на источник коим является в данном случае obReferenceObject. Нужно делать два баиндера, но можно использовать один лист.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: ObjectBinder связывает излишние свойства
От: selfmade США about:blank
Дата: 02.03.06 05:38
Оценка:
Здравствуйте, Дьяченко Александр, Вы писали:

ДА>Здравствуйте, selfmade, Вы писали:


S>>Задача такая: Имеется форма с двумя комбобоксами, отображающими список объектов одинакового типа (Person). На форме лежат два ObjectBinder компонента. Один для связывания списка комбобокса со списком объектов Person (один и тот же ObjectBinder используется как DataSource двух контролов), второй для связывания свойств рабочего объекта Marriage со значениями контролов на форме.


S>>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение. Мне кажется, что такое поведение ObjectBinder неверно. Не должен ObjectBinder, установленный как DataSource у ряда контролов, связывать также выбранные значения этих контролов.


ДА>Работает так же как BindingSource в .NET 2.0. Если надо разные, то два варианта:

ДА>1.

ДА>
         ->> BindingSource1 -> Control1
ДА>        /
ДА>Данные <
ДА>        \
         ->> BindingSource2 -> Control2
ДА>

ДА>2.

На какое свойство контрола Control1 источник связывания BindingSource1 привязывает данные?
В моём примере я хочу привязать одни и те же данные на свойство DataSource обоих контролов, при этом свойства SelectedValue в контролах связывать между собой мне не надо.


ДА>
                           ->> BindingSource1 -> Control1
ДА>                          /
ДА>Данные -> BindingSource0 <
ДА>                          \
                           ->> BindingSource2 -> Control2
ДА>

ДА>Потому что Position определен на уровне BindingSource и он один для всех. Для ObjectBinder должно быть так же.
С уважением. selfmade.
Re[3]: ObjectBinder связывает излишние свойства
От: IT Россия linq2db.com
Дата: 02.03.06 05:42
Оценка:
Здравствуйте, selfmade, Вы писали:

S>В моём примере я хочу привязать одни и те же данные на свойство DataSource обоих контролов, при этом свойства SelectedValue в контролах связывать между собой мне не надо.


Ложи на форму два баиндера и связывай их с одним листом.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: ObjectBinder связывает излишние свойства
От: selfmade США about:blank
Дата: 02.03.06 05:59
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, selfmade, Вы писали:


S>>Почему-то первый ObjectBinder связывает не только списки контролов со списком объектов, но также и выбранные значения контролов, т.е. при выборе значения в одном контроле, второй контрол тоже изменяет значение.


IT>Так работает CurrencyManager. Он один на источник коим является в данном случае obReferenceObject. Нужно делать два баиндера, но можно использовать один лист.


Спасибо. Персональный байндер на контрол работает отлично.

Но вопрос единственного CurencyManager на один на источник остаётся. Это удобно, если хочется ходить по листу и отображать позицию в листе на множество контролов. Это неудобно, если хочется всего лишь иметь общий список и независимые позиции курсора в списке в каждом контроле.
С уважением. selfmade.
Re[4]: ObjectBinder связывает излишние свойства
От: selfmade США about:blank
Дата: 02.03.06 06:40
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, selfmade, Вы писали:


S>>В моём примере я хочу привязать одни и те же данные на свойство DataSource обоих контролов, при этом свойства SelectedValue в контролах связывать между собой мне не надо.


IT>Ложи на форму два баиндера и связывай их с одним листом.


Учитывая то, что таких контролов у меня будет много, я унаследовал от ComboBox и добавил ObjectBinder в новый контрол.
С уважением. selfmade.
Re[3]: ObjectBinder связывает излишние свойства
От: Дьяченко Александр Россия  
Дата: 02.03.06 06:47
Оценка:
Здравствуйте, selfmade, Вы писали:

S>Но вопрос единственного CurencyManager на один на источник остаётся. Это удобно, если хочется ходить по листу и отображать позицию в листе на множество контролов. Это неудобно, если хочется всего лишь иметь общий список и независимые позиции курсора в списке в каждом контроле.


Межу списком и отдельными биндерами на каждый контрол надо сделать прослойку из еще одного биндера и список менят именно у него.
... << RSDN@Home 1.2.0 alpha rev. 642>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.