Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > как перезагрузить из DataSource в ДатаГриде?


Автор: St33l 5.10.2009, 15:51
Такая проблема: есть textbox. пользователь вводит в него некоторое числовое значение. это числовое значение присваивается некотрому объекту, который выступает в качестве датасорса для таблицы. В зависимости от значения соответственно в таблице тоже меняются числа.
а проблема вот в чем: когда я ввожу какое-нибудь число в текстбокс и жму обновить, то в таблице ничего не меняется, но достаточно скроллбаром (таблица длинная) утащить ячейку за поле видимости и притащить обратно, как я вижу новое значение.
по кнопке обновить идет просто присваивание датасорса таблице.

как обойти это? может какой-то метод есть, а я не знаю )

Автор: jonie 5.10.2009, 21:57
вам нужно в вашем объекте реализовать INotifyPropertyChanged.
пример в аттаче.

Автор: St33l 6.10.2009, 08:36
как должен работать пример? я вводу в текстбокс значение, щелкаю на таблицу и там оно обновляется.
после того, как я из кода вырезал упоминания о INotifyPropertyChanged и т.п., то работа не изменилась.

Автор: jonie 6.10.2009, 09:41
St33l, просто я привязал к одному BindingSource-у, привяжите к двум разным BindingSource-ам грид и тексто бокс и всё будет как у вас.
Обновленный пример в аттаче.

(переходите фокусом ввода в другой контрол, не в грид - иначе грид перезапросит данные)


UPD:
Впрочем и предыдущий пример работает, если вы будете ставить НЕ на грид фокус (добавьте еще ченить в форму и попробуйте)

Автор: St33l 8.10.2009, 09:12
чет не то у меня. смотрите, как выглядит в реале моя форма:

http://img34.imageshack.us/i/formm.png/

1. В программе есть 5 объектов (А-E класса Shihta (из них 1 наследник ее с перегруженным свойством))
2. Есть 2 List-а. lstShihtatmp и lstShihta. В певром находятся все 5 этих объектов, а во втором 2-х из них нет (не нужны просто).
3. Первая таблица черпает данные из lstShihtatmp, а вторая lstShihta (через биндингсорсы этих листов, 2 биндинга выходит).

Мои затруднения:
Видите колонку П.П.П.? Рассмотрим ПУТ и ЖРС. Когда я меняю значение П.П.П. у ПУТ, то автоматически пересчитывается (в ручную не вводится) значение П.П.П, у ЖРС. Я знаю, что оно пересчиталось, но визуально этого не вижу, пока не щелкну на эту ячейку или не уведу скроллом ячейку из поля видимости. Почему так происходит и как исправить?

Автор: jonie 8.10.2009, 09:32
St33l, а я грю что надо наследоваться от нужного.
Кроме того List<T> также не наследует INotifyPropertyChanged - используйте BindingList<T>, в item-ы которого должны быть запиханы также классы, наследованные от INotifyPropertyChanged.

И воообще при объяснении наследования - сделайте диаграмму, на слух тяжело воспринимать.

Автор: St33l 8.10.2009, 10:38
1. изменил List на BindingList
2. Класс Shihta изменил как в примере:
Код

public class Shihta : INotifyPropertyChanged
{
        public event PropertyChangedEventHandler PropertyChanged;

        protected double _PPP;
        public virtual double PPP
        {
            get { return _PPP; }
            set
            {
                if (value < 0) throw new ArgumentException("Ошибка ввода значения параметра", "Потери при прокаливании");
                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("PPP"));
                else _PPP = value;
            }
        }
}


Теперь после ввода в ячейку П.П.П. и выхода из нее ее значение тут же возвращается на старое. Это только для П.П.П., для других такое не происходит, потому в классе для них ничего не менял.

Автор: St33l 8.10.2009, 12:39
виноват, нашел ошибку в коде выше. сейчас так:

Код

public class Shihta : INotifyPropertyChanged
{
        public event PropertyChangedEventHandler PropertyChanged;

        protected double _PPP;
        public virtual double PPP
        {
            get { return _PPP; }
            set
            {
                if (value < 0) throw new ArgumentException("Ошибка ввода значения параметра", "Потери при прокаливании");
                else _PPP = value;
                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("PPP"));
            }
        }
}


Ничего не сбрасывает. но после ввода числа в П.П.П. например ПУТа, то значение П.П.П, для ЖРМ пересчитывается, но все так же не отображается, пока не кликнешь в ячейку или не проскроллить.

Автор: uranpro 8.10.2009, 13:12
А нельзя самому обновить ее ? задать значение, примерно:
Код

GV.Rows[GV.SelectedIndex].Cells["ППП"] = val

Автор: St33l 8.10.2009, 16:42
Не, оно вычисляемое. Зависит от того, что ввести в п.п.п. пут

Автор: jonie 8.10.2009, 19:53
St33l, сделайте и выложите минимальный пример. У вас где-то 100% косяк)

Автор: St33l 9.10.2009, 10:29
Выкладываю пример. В данном архиве код, который отражает мою ситуацию.

Автор: St33l 9.10.2009, 10:30
А здесь код уже подредактирован в соответствии с рекомендациями jonie

Автор: jonie 9.10.2009, 13:45
ну вот.
меняйте класс на это:
Код

    public class MySecondClass : MyFirstClass
    {
        public MySecondClass(MyFirstClass firstClass)
        {
            this.firstClass = firstClass;
            this.firstClass.PropertyChanged += new PropertyChangedEventHandler(firstClass_PropertyChanged);
        }

        void firstClass_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if(e.PropertyName == "PPP") {
                this.PPP = firstClass.PPP / 2;
            }
        }
        
        private MyFirstClass firstClass;
        
    }

и все будет как вы хотите.

Автор: St33l 9.10.2009, 16:25
заработало ) спасибо большое. еще такой вопрос: сейчас после нажатия кнопки "заполнить" П.П.П. перестало считаться. считается только после того, как ввести что-то в П.П,П. объекта 1.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)