我有一组组件,它们共享一些全局变量来控制公共属性,例如样式特征。
这些当前通过全局类在运行时访问,例如MyCompsSettings(). SomeProperty。
我认为允许用户在设计时配置其中的一些属性可能很有用,所以我将全局类转换为组件,并且因为这些属性需要在MyCompsSettings()和我的TMyCompsSettings组件的示例之间共享,所以我使用全局变量来存储状态,例如。
type
TMyCompsSettings = class(TComponent)
private
function GetBackgroundColor(): TColor;
procedure SetBackgroundColor(const v: TColor);
function GetTitleText(): string;
procedure SetTitleText(const v: string);
published
property BackgroundColor: TColor read GetBackgroundColor write SetBackgroundColor;
property TitleText: string read GetTitleText write SetTitleText;
end;
implementation
var
gBackgroundColor: TColor;
gTitleText: string;
function TMyCompsSettings.GetBackgroundColor(): TColor;
begin
Result := gBackgroundColor;
end;
procedure TMyCompsSettings.SetBackgroundColor(const v: TColor);
begin
gBackgroundColor := v;
end;
function TMyCompsSettings.GetTitleText(): string;
begin
Result := gTitleText;
end;
procedure TMyCompsSettings.SetTitleText(const v: string);
begin
gTitleText := v;
end;
但是,我忽略了IDE还将维护var状态,因此当我:
1.将TMyCompsSettings组件添加到表单
1.在对象检查器中将MyCompsSettings1.TitleText设置为“ABC”
1.打开其他项目
1.将TMyCompsSettings组件添加到表单
- 〉MyCompsSettings1.TitleText已经是'ABC'!
当然,这是显而易见的,但我没有考虑到这一点,这打破了我的整个模型。
是否有正确的方法来做到这一点?例如,在设计时使用字段,在运行时使用变量,例如:
type
TMyCompsSettings = class(TComponent)
private
FAuthoritative: Boolean; // Set to true for first instance, which will be MyCompsSettings()
FBackgroundColor: TColor;
FTitleText: string;
function GetBackgroundColor(): TColor;
procedure SetBackgroundColor(const v: TColor);
function GetTitleText(): string;
procedure SetTitleText(const v: string);
published
property BackgroundColor: TColor read GetBackgroundColor write SetBackgroundColor;
property TitleText: string read GetTitleText write SetTitleText;
end;
implementation
function TMyCompsSettings.GetBackgroundColor(): TColor;
begin
if FAuthoritative or ( csDesigning in ComponentState ) then
Result := FBackgroundColor
else
Result := MyCompsSettings().BackgroundColor;
end;
procedure TMyCompsSettings.SetBackgroundColor(const v: TColor);
begin
if FAuthoritative or ( csDesigning in ComponentState ) then
FBackgroundColor := v
else
MyCompsSettings().BackgroundColor := v;
end;
function TMyCompsSettings.GetTitleText(): string;
begin
if FAuthoritative or ( csDesigning in ComponentState ) then
Result := FTitleText
else
Result := MyCompsSettings().TitleText;
end;
procedure TMyCompsSettings.SetTitleText(const v: string);
begin
if FAuthoritative or ( csDesigning in ComponentState ) then
FTitleText := v
else
MyCompsSettings().TitleText := v;
end;
1条答案
按热度按时间smtd7mpg1#
由于IDE是一个进程,因此进程中的全局变量将保留在进程中。
如果您希望能够跟踪IDE中不同项目之间的设置(如果它们在一个项目组中,则可能同时打开两个窗体),则需要找到一种跟踪它们的方法。
也许最简单的方法是将设置保存在一个对象中-可以在
initialization
节中加载一个全局对象,并在finalization
节中释放。您的基于表单的TComponent可以检查它们是否处于设计模式,如果它们处于设计模式,则它们创建一个新的单独的对象副本,如果不是,则它们连接到对象的全局示例。其他访问这些设置的组件都将使用全局对象--为了确保对象的内容与设计时版本相匹配,您需要用任何加载的表单版本覆盖全局对象。您可以在
TComponent
的Loaded
例程中完成此操作。这段代码是未检查的,但应该给予你一个大纲,它可能如何工作。
您还需要确保在
TMySettingsComponent
中,当用户更改属性时更新全局对象。这可能非常简单: