Итак, у меня было опубликованное свойство SomeThings, в котором было более 32 элементов, которые необходимо было разделить (или не опубликовать).Я решил логически разделить существующие элементы (классифицировать их), что усложнило процесс, если бы я хотел минимизировать испорченный код для существующих пользователей.
Итак, я создаю два новых свойства, например TheseThings, OtherThings.
Вместо того чтобы удалять старое свойство SomeThings, я изменил его с опубликованного на общедоступный, чтобы существующий пользовательский код не сломался, если бы он назначил (большинство) старых свойств ему во время выполнения.
Для того, чтобычтобы избежать ошибки при открытии формы, содержащей элементы SomeThings, я переопределил DefineProperties (), который корректно переместил элементы в свойства TheseThings или OtherThings.
procedure TMyUnit.ReadSomeThings(Reader: TReader);
{}
function ReadSet(): string;
var
EnumName: string;
begin
Result := '';
try
if Reader.ReadValue <> vaSet then
raise Exception.Create('Not a set');
while True do
begin
EnumName := Reader.ReadStr;
if EnumName = '' then Break;
Result := Result + EnumName + ',';
end;
except
while Reader.ReadStr <> '' do begin end;
raise;
end;
end;
{}
function NextWord(var P: PAnsiChar): AnsiString;
var
I: Integer;
begin
I := 0;
while not (P[I] in [',', ' ', #0,']']) do
Inc(I);
SetString(Result, P, I);
while P[I] in [',', ' ',']'] do
Inc(I);
Inc(P, I);
end;
{}
var
s: AnsiString;
P: PAnsiChar;
enumName: AnsiString;
ttSet: TTheseThings;
otSet: TOtherThings;
begin
s := AnsiString( ReadSet() );
if s = '' then
Exit;
otSet := [];
ttSet := [];
P := PAnsiChar( s );
enumName := NextWord(P);
while enumName <> '' do
begin
// Convert item names of OtherThings property to newer names (changed prefix)
if SameText( enumName, 'sTwo' ) then
otSet := otSet + [oTwo ]
else
if SameText( enumName, 'sThree' ) then
otSet := otSet + [ oThree ]
else
...
// Exiting items of TTheseThings have same name as old TSomeThings to minimize breakage
else
if SameText( enumName, 'sOne' ) then
ttSet := ttSet + [ sOne ]
else
if SameText( enumName, 'sFour' ) then
ttSet := ttSet + [ sFour ]
else
...
enumName := NextWord(P);
end;
if ttSet <> [] then
SetTheseThings(ttSet);
if otSet <> [] then
SetOtherThings(otSet);
end;
procedure TMyUnit.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty( 'SomeThings', ReadSomeThings, nil, False );
end;
Примечание. В исходном коде использовался GetEnumValue ();преобразовать enumName в перечислитель, но он постоянно давал мне искаженные заданные значения, поэтому я выбрал это более простое (но более многословное) решение