Свойство Redeclare Width для пользовательского компонента Delphi - PullRequest
3 голосов
/ 23 ноября 2010

У меня есть пользовательский компонент Delphi, происходящий из TGraphicControl.Его класс объявлен следующим образом:

TMyLabel = class(TGraphicControl)
private
  ...
protected
  ...
public
  ...
published
  property Height;
  property Width write SetWidth;
  ...
end;

Реализация SetWidth лежит дальше:

procedure TMyLabel.SetWidth(const Value: Integer);
begin
  if (Value >= 0) and (Value <> Width)
  then begin
    inherited Width := Value;
    // Do some other stuff
    ...
  end;
  MessageDlg('Test', mtInformation, [mbOK], 0);
end;

В настоящее время я вызываю SetWidth, когда ширина компонента программно изменяется во время выполнения или приВремя разработки путем ввода значения в соответствующем поле инспектора объекта.Однако, когда я изменяю размер компонента во время разработки с помощью мыши, поле «Ширина» инспектора объектов обновляется, но окно сообщения не отображается, поэтому моя процедура SetWidth не вызывается.

Мне нужно, чтобы вызывался SetWidthизменяя размер компонента при помощи мышки, чтобы я мог установить флаг для процедуры рисования, чтобы знать, когда она должна делать какие-то другие вещи (кроме простого перерисовывания компонента).Есть ли способ добиться этого?

Ответы [ 3 ]

6 голосов
/ 23 ноября 2010

Я не могу проверить прямо сейчас, но я подозреваю, что дизайнер изменяет размеры вашего элемента управления с помощью SetBounds (), а не устанавливает индивидуальные свойства left, top, width и height.

К счастью, SetBounds ()виртуальный, так что вы можете просто переопределить это в своем пользовательском классе управления.

6 голосов
/ 23 ноября 2010

Пока ответ Мэйсона Уилера является ответом на ваш вопрос, я хотел бы предупредить вас.

Переопределение свойств может дать странные результаты, поскольку у вас не может быть «виртуальных» свойств, а SetWidth также не является виртуальным. Если кто-то использует потомка вашего класса для установки свойства Width, ваш код вызываться не будет. Поэтому я не советую переопределять свойства таким образом.

var Control: TControl;
begin
 Control := MyLabel;
 Control.Width := 5000; // TMyLabel.SetWidth is not called!!

Более того: установка свойства Width - не единственный способ изменить ширину элемента управления, как Deltics объясняет . Вы должны переопределить TControl.SetBounds.

var MyLabel: TMyLabel;
begin
 MyLabel.SetBounds(0, 0, 100, 100); // TMyLabel.SetWidth nor TControl.SetWidth is called!!

Но похоже, что вы хотите ограничить ширину своего элемента управления. Тогда вам лучше переопределить TControl.CanResize , который сделан для этой цели. Или, если вы просто хотите отреагировать на изменение размера, лучше переопределить TControl.Resize .

4 голосов
/ 23 ноября 2010

Когда вы заново определяете Width, вам нужно указать для него read и write , иначе вы не сможете изменить его в Инспекторе объектов.Если вы не собираетесь менять способ чтения, просто дайте ему фиктивную функцию:

procedure TMyLabel.GetWidth: Integer;
begin
  result := inherited Width;
end;
...