Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Событие при изменении объекта TObjectList  (Прочитано 27371 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
SCRIBE
Гость
« : 02-10-2015 07:30 » 

Привет.

Был бы рад за помощь в решении маленькой задачки.

Есть объект (TMyObject), есть список с этими самими объектами (TObjectList<TMyObject>).

Как из списка узнать что объект изменили? В смысле изменили какое-то его свойство...

Пример:
Код: (Delphi)
TMyObject = class
  oName: string;
end;

TMyObjectList = class(TObjectList<TMyObject>)
 
end;

procedure Form1.Button1.Click(Sender: TObject);
var
  Obj: TMyObject;
  List: TMyObjectList;
Begin
 List:= TMyObjectList.Create;
 Obj:= TMyObject.Create;
 List.Add(Obj);
 List[0].oName:= 'Ky'; // Вот тут неплохо бы узнать что объекту в списке изменили свойство
end;

Вообще задача в сохранении значений этих объектов сразу же после изменения. Беда в том что сохраняет все значения объект списка, а не сам единичный объект (там то это можно отловить через property т.е. сеттер). Можно конечно сделать специальный метод для изменения объектов в списке, но все равно их можно будет и так изменить, без этого метода, а это нехорошо  Улыбаюсь И просто вызывать метод сохранения после изменения тоже не хочется, в общем такой каприз, список должен сам как-то узнать что мир уже не станет прежним  Скромно так...  Отлично
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 02-10-2015 07:59 » 

..::SCRIBE::.., определись, критично ли время (и/или количество) сохранения этого списка ? Скажем, к примеру, для юзера эти несчастные 10 миллисекунд - тьфу, можно просто определить факт доступа к настройкам и потом всё разом сохранить.

Или же время критично ?
Записан

SCRIBE
Гость
« Ответ #2 : 02-10-2015 08:07 » 

Время не особо критично, количество элементов будет не слишком большое (штук 20 макс.). Но сам способ как это можно сделать интересен.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 02-10-2015 08:12 » 

..::SCRIBE::.., наверное, кроме как все мемберы в функции доступа оборачивать (и там флажки взводить или счётчики вести), особо ничего не придумаешь
Записан

SCRIBE
Гость
« Ответ #4 : 02-10-2015 08:17 » 

Там в объекте TObjectList нашел методы OnNotify/Notify, их нельзя использовать? Пока не нашел внятной информации по ним.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 02-10-2015 08:36 » 

..::SCRIBE::.., я не знаю ) Пробуй http://keeper89.blogspot.ru/2011/07/delphi-2.html#a333
Записан

zubr
Гость
« Ответ #6 : 02-10-2015 10:12 » 

..::SCRIBE::.., ну раз объект твоего собственного класса, то ты можешь делать с ним все что хочешь. Создай свое событие данного класса, которое вызывается при изменении нужного свойства. Событие вызывать к примеру в функции записи свойства.

Код:
TMyClass = class(TObject)
private
  FName: string;
  FOnNameEvent: TNotifyEvent;
private
  procedure SetName(value: string);

public
  property Name: string read FName write SetName;
  propery OnNameEvent read FOnNameEvent write FOnNameEvent;
end;

procedure TMyClass.SetName(value: string);
begin
  FName := value;

  if Assigned(FOnNameEvent) then
  FOnNameEvent(Self);
end;


procedure MyNameEvent(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to MyListOfMyClassObjects.Count -1 do
  begin
    if Sender = MyListOfMyClassObjects.Item[i] then
    begin
       MessageBox(0, PChar(TMyClass(MyListOfMyClassObjects.Item[i]).Name), nil, MB_OK);
       break;
    end;
  end;
end;

var
  MyObject: TMyClass;

  MyObject := TMyClass.Create;
  MyObject.OnNameEvent := MyNameEvent;
  MyListOfMyClassObjects.Add(MyObject);  
« Последнее редактирование: 02-10-2015 10:15 от zubr » Записан
SCRIBE
Гость
« Ответ #7 : 02-10-2015 11:16 » 

Да, то что нужно! Спасибо большое.

Добавлено через 6 минут и 18 секунд:
И еще, обязательно писать 2 раза private для свойств и для методов? Или это просто опечатка?)
« Последнее редактирование: 02-10-2015 11:22 от SCRIBE » Записан
zubr
Гость
« Ответ #8 : 02-10-2015 11:44 » 

Это для удобства. Отдельно приват для переменных и отдельно для методов, чтобы их отделить. Но это на любителя как говорится.

З.Ы. Код тут вообще показан как схема, а не как абсолютное руководство к действию.
Записан
SCRIBE
Гость
« Ответ #9 : 02-10-2015 11:49 » 

Ясно, все же сакральный смысл есть Улыбаюсь
Ну, почти доделал, сейчас протестим... Компилируется, уже хорошо)))

Добавлено через 34 минуты и 7 секунд:
Дополнение: процедура события должна быть методом какого-то объекта (MyNameEvent). Иначе ошибка.
« Последнее редактирование: 02-10-2015 12:23 от SCRIBE » Записан
zubr
Гость
« Ответ #10 : 03-10-2015 04:47 » 

Дополнение: процедура события должна быть методом какого-то объекта (MyNameEvent). Иначе ошибка.
Не обязательно. Это должен быть метод класса, не обязательно того же. К примеру, это может быть метод формы:
Код:
procedure TForm1.MyNameEvent(Sender: TObject);
Кстати, можно вместо кода:
Код:
for i := 0 to MyListOfMyClassObjects.Count -1 do
  begin
    if Sender = MyListOfMyClassObjects.Item[i] then
    begin
       MessageBox(0, PChar(TMyClass(MyListOfMyClassObjects.Item[i]).Name), nil, MB_OK);
       break;
    end;
  end;
сделать проще:
Код:
MessageBox(0, PChar(TMyClass(Sender).Name), nil, MB_OK);
Записан
SCRIBE
Гость
« Ответ #11 : 07-10-2015 09:49 » 

Немного неправильно выразился, имел ввиду именно то что вы сказали, любой метод, но не процедура.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines