Модераторы: gambit, Partizan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Привязка данных объекта из списка 
V
    Опции темы
Felan
Дата 21.4.2009, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Прочитал статью на RSDN Привязка данных в Windows Forms.

Привязка единичного объекта к контролам отлично сработала.
А вот привязка к объекту из списка не работает.

Делаю так, для пробы только для txbFIO:


Код

    public partial class RelationPeoplesFrm : Form
    {
        private readonly List<Men> _PeoplesList = new List<Men>();

        public RelationPeoplesFrm()
        {
            InitializeComponent();

            var binding = new Binding( "Text", _PeoplesList, "FullName" );
            txbFIO.DataBindings.Add( binding );

            BindingManager.PositionChanged += BindingManager_PositionChanged;

            dataBind();
        }

        private void BindingManager_PositionChanged(object sender, EventArgs e)
        {
            updateUI();
        }

        private void dataBind()
        {
            lsbPeoples.DataSource = null;
            lsbPeoples.DataSource = _PeoplesList;
            lsbPeoples.DisplayMember = "FullName";

            BindingManager.Position = lsbPeoples.SelectedIndex + 1;
 
            updateUI();
        }

        private void updateUI()
        {
            btnEdit.Enabled = _PeoplesList.Count > 0;
            btnDelete.Enabled = lsbPeoples.SelectedIndex >= 0;
        }

        private BindingManagerBase BindingManager
        {
            get
            {
                return BindingContext[ _PeoplesList ];
            }
        }

        private void btnAddNew_Click(object sender, EventArgs e)
        {
            var men = new Men();
            var dlgNewMen = new MenFrm(men);

            if (dlgNewMen.ShowDialog(this) != DialogResult.OK)
                return;

            _PeoplesList.Add(men);
            dataBind();
        }

        private void lsbPeoples_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lsbPeoples.SelectedIndex >= 0)
            {
                var m = _PeoplesList[lsbPeoples.SelectedIndex];
//                txbFIO.Text = m.FullName;
                txbBirthday.Text = m.Birthday.ToString("dd MMMM yyyy");
                txbAdress.Text = m.Address.ToString();

                BindingManager.Position = lsbPeoples.SelectedIndex + 1;
            }
            else
            {
                txbFIO.Clear();
                txbBirthday.Clear();
                txbAdress.Clear();
            }
            updateUI();
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
            var dlgNewMen = new MenFrm(_PeoplesList[lsbPeoples.SelectedIndex]);

            if (dlgNewMen.ShowDialog(this) != DialogResult.OK)
                return;

            dataBind();
        }

        private void lsbPeoples_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (((ListBox) sender).SelectedIndex < 0)
            {
                btnAddNew_Click(null, null);
            }
            else
            {
                btnEdit_Click(null, null);
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            _PeoplesList.RemoveAt(lsbPeoples.SelectedIndex);
            dataBind();
        }
    }


После btnAddNew_Click и выбора с lsbPeoples (это ListBox на форме) элемента, все контролы показывают правильные данные, а txbFIO - пустой.

В чем проблема, никак не пойму?


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
Partizan
Дата 21.4.2009, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



Felan, в том, что у типа List<Men> нет свойства FullName


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Felan
Дата 21.4.2009, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Это свойство есть у класса Men.
 Класс Men выглядит так:

Код

using System;

namespace Task1_WinForms.Classes
{
    public class Men
    {
        private static readonly DateTime _maxBithdayDate = new DateTime(9998, 12, 31);
        private static readonly DateTime _minBithdayDate = new DateTime(1753, 1, 1);

        private readonly Address _Address = new Address();
        private DateTime _Birthday = _minBithdayDate;

        public string Name { get; set; }
        public string SecondName { get; set; }
        public string Family { get; set; }

        public DateTime Birthday
        {
            get { return _Birthday; }
            set
            {
                if ((value < _minBithdayDate) || (value > _maxBithdayDate))
                {
                    throw new ArgumentOutOfRangeException();
                }
                _Birthday = value;
            }
        }

        public Address Address
        {
            get { return _Address; }
        }

        public string FullName
        {
            get 
            { 
                return String.Format("{0} {1} {2}", Family, Name, SecondName); 
            }
        }
    }
}




Это сообщение отредактировал(а) Felan - 21.4.2009, 11:08


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
diadiavova
Дата 21.4.2009, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 16
Всего: 142



Может быть дело в том, что FullName - ReadOnly свойство. Всё-таки привязка должна быть двусторонней.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Partizan
Дата 21.4.2009, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



Цитата

Это свойство есть у класса Men.


Felan,  Дык binding идёт с объектом типа List<Men>, а не с объектом типа Men...разницу чувствуете?


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Felan
Дата 21.4.2009, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Разницу я чувствую.
Я даже ссылку на статью привел, в которой описан этот метод привязки данных... (Пункт 3.2)

И даже в MSDN про него написано...

Вот я только не чувствую, что я не так сделал, и почему, в статье и MSDN говорится, что это должно работать, а у меня не работает.

Вполне возможно, что я действительно страшно ступил smile Ну так объясните кто-нибудь, где???

Добавлено @ 12:20
Цитата(diadiavova @  21.4.2009,  13:41 Найти цитируемый пост)
Может быть дело в том, что FullName - ReadOnly свойство. Всё-таки привязка должна быть двусторонней. 

Попробую дома какой-нибудь сеттер к нему сделать, хотя странно как-то. Привязка же не обязательно двусторонней должна быть... вроде...
Ну и я бы понял, если бы оно в таком случае не писалось, но почему не читается то... 

Это сообщение отредактировал(а) Felan - 21.4.2009, 12:34


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
-Mikle-
Дата 21.4.2009, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 8
Всего: 59



Felan, я не стал вникать в чем дело именно у тебя в коде, а просто покажу другой, рабочий вариант.
Еще у тебя есть бесполезный код связанный с использованием List<> (это dataBind() и lsbPeoples_SelectedIndexChanged()). Вместо этого лучше использовать BindingList<>. Также, рекомендую реализовать интерфейс INotifyPropertyChanged в классе Men.
Вобщем вот код, смотри:
класс Men
Код

    public class Men : INotifyPropertyChanged
    {
        string name;
        string family;

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }

        public string Family
        {
            get { return family; }
            set
            {
                family = value;
                OnPropertyChanged("Family");
            }
        }

        public string FullName { get { return string.Concat(family, " ", name); } }


        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }


код формы
Код

        BindingList<Men> peoples = new BindingList<Men>();

        public Form1()
        {
            InitializeComponent();

            textBox1.DataBindings.Add("Text", peoples, "FullName");

            listBox1.DataSource = peoples;
            listBox1.DisplayMember = "FullName";

            // тестовые данные
            peoples.Add(new Men() { Name = "Ivan", Family = "Konkov" });
            peoples.Add(new Men() { Name = "Petr", Family = "Rolton" });
            peoples.Add(new Men() { Name = "Dilan", Family = "Koks" });
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            // благодаря использованию BindingList<> вместо List<>, можно 
            // просто добавлять в коллекцию значения, а обновление произойдет автоматом
            peoples.Add(new Men() { Name = "RandomName" + (new Random().Next(9999)), Family = "New" });
        }

        private void btnEditName_Click(object sender, EventArgs e)
        {
            // получаем текущий элемент из контекста привязки
            // можно и через SelectedValue, но это будет отступлением от идеи
            Men currentItem = BindingContext[peoples].Current as Men;
            if (currentItem == null) return;

            // благодаря реализованному интерфейсу INotifyPropertyChanged,
            // мы опять таки не делаем обновление ручками
            currentItem.Name = "RandomName" + (new Random().Next(9999));
        }



--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Felan
Дата 22.4.2009, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Сделал по твоему примеру. Все работает. Даже не пришлось реализовывать INotifyPropertyChanged. У меня нет вариантов, когда источник меняется не через модель.

В принципе я свою проблему решил smile Привязка работает...
Но тему закрывать не буду, т.к. хотелось бы все таки выяснить, что не так было в изначальном варианте... ну для понимания сути проблемы...


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
-Mikle-
Дата 22.4.2009, 08:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 8
Всего: 59



Прикрепи проект с ошибкой из первого поста сюда, мне будет проще найти ошибку...


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Felan
Дата 22.4.2009, 08:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Проект приложил.
Еще там один вопрос в комментарии написал, в форме MenFrm, по привязке даты к контролу.

Кстати, не до оценил всю глубину этой привязки. Уже когда сделал по твоему.
Получается что все равно надо реализовывать INotifyPropertyChanged, иначе при закрытии диалога не обновляются данные на основной форме...
Если его сделать (тут еще есть вопросы по поводу вложенного класса Address, но это завтра наверно поковыряюсь сам...) то данные обновляются сразу. Но при этом не работает кнопка "отмена". Я переделал обновление источника на "при валидации" и сделал ей causeValidation = false. С отменой нормально все, а вот при принятии, обновление происходит сразу при нажатии на кнопку. Т.е. если например нажать на кнопку и не отпуская клавиши мыши убрать курсор, то вроде как бы и не было нажатия, а данные обновились.
Можно это как-то обойти?

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  Task1_WinForms.zip 268,21 Kb


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
diadiavova
Дата 22.4.2009, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 16
Всего: 142



Посмотрел проект, и вот на вопрос 

Цитата(Felan @  21.4.2009,  07:02 Найти цитируемый пост)
После btnAddNew_Click и выбора с lsbPeoples (это ListBox на форме) элемента, все контролы показывают правильные данные, а txbFIO - пустой.

В чем проблема, никак не пойму? 

Отвечаю

Раскоментируй строку
Код

//                txbFIO.Text = m.FullName;



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Felan
Дата 22.4.2009, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Цитата(diadiavova @  22.4.2009,  14:26 Найти цитируемый пост)
Посмотрел проект, и вот на вопрос 

Если бы еще ты полностью и внимательно прочитал вопрос, то заметил бы, что речь идет о биндинге списка к полю контрола, а не о том, как присвоить полю контрола данные. smile

Я даже статью привел, в которой описанный способ освещен.

Так что ответ мимо тазика :(


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
diadiavova
Дата 22.4.2009, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 16
Всего: 142



В строке 68 в первом посте ты присваиваешь номер позиции. Новый номер почему-то не присваивается(всё время равен -1). У меня сейчас пока нет времени разбираться в чём дело, может потом, или сам.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
-Mikle-
Дата 22.4.2009, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 8
Всего: 59



Ответ зарыт в недрах реализации биндинга.
Предполагаю следующее:
Весь косяк из-за List, точнее из-за отсутствия у него события о его изменении. То есть, когда ты биндишь к TextBox'у список, он пустой в этот момент и биндинг "ничего не делает". После добавления в список нового объекта, биндинг TextBox'а по прежнему ничего не делает, так как не знает, что в списке появился новый элемент. Если, к примеру, добавить один элимент в список до привзяки, то все начинает работать волшебным образом.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
diadiavova
Дата 22.4.2009, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 16
Всего: 142



-Mikle-, в смысле привязку надо выполнять после того, как все элементы добавлены? smile 


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.0671 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.