BCB里面的属性,改变它们的值时,大多数情况下都需要调用相关的函数。比如这儿: __property TButtonSet VisibleButtons = {read=FVisibleButtons, write=SetVisible, default=1023}; 当你读取属性VisibleButtons时,它直接访问变量FVisibleButtons,给他赋值时就调用 函数SetVisible。如果你直接写成 DBNavigator1->VisibleButtons >> nbPost; 的话,就 是直接修改class中的变量FVisibleButtons,因为没有赋值符号,因而没有调用SetVisible 这个函数。所以属性的值发生变化了,但是它没有调用相关的函数来真正显示/隐藏那些按 钮。所以必须写成 DBNavigator1->VisibleButtons = DBNavigator1->VisibleButtons >> nbPost; 这样才会调用SetVisible这个函数。 但是需要注意,对于其他的控件的一些属性,即使是上面的写法,虽然会发生函数调用, 但是可能还是无法看到效果。比如TDBGrid的Options属性,如果还是使用: DBGrid1->Options = DBGrid1->Options >> dgEditing; 你就会发现根本不起作用。原因是什么呢?首先我们来看看他的定义: __property TDBGridOptions Options = {read=FOptions, write=SetOptions, default=3325}; 这样一看,你会发现它的定义,和上面的VisibleButtons一样啊,怎么就不行了呢?这个还 需要看看源程序中TDBGrid的SetOptions的代码: procedure TCustomDBGrid.SetOptions(Value: TDBGridOptions); const LayoutOptions = [dgEditing, dgAlwaysShowEditor, dgTitles, dgIndicator, dgColLines, dgRowLines, dgRowSelect, dgAlwaysShowSelection]; var NewGridOptions: TGridOptions; ChangedOptions: TDBGridOptions; begin if FOptions <> Value then begin NewGridOptions := []; if dgColLines in Value then NewGridOptions := NewGridOptions + [goFixedVertLine, goVertLine]; if dgRowLines in Value then NewGridOptions := NewGridOptions + [goFixedHorzLine, goHorzLine]; if dgColumnResize in Value then NewGridOptions := NewGridOptions + [goColSizing, goColMoving]; if dgTabs in Value then Include(NewGridOptions, goTabs); if dgRowSelect in Value then begin Include(NewGridOptions, goRowSelect); Exclude(Value, dgAlwaysShowEditor); Exclude(Value, dgEditing); end; if dgEditing in Value then Include(NewGridOptions, goEditing); if dgAlwaysShowEditor in Value then Include(NewGridOptions, goAlwaysShowEditor); inherited Options := NewGridOptions; if dgMultiSelect in (FOptions - Value) then FBookmarks.Clear; ChangedOptions := (FOptions + Value) - (FOptions * Value); FOptions := Value; if ChangedOptions * LayoutOptions <> [] then LayoutChanged; end; end; 注意,上面的代码,首先是一个判断语句 if FOptions <> Value then,就是说参数 Value 的值和原来的 FOptions 不同时才会执行下面的代码。但是如果你使用下面的 写法时:DBGrid1->Options = DBGrid1->Options >> dgEditing; 编译器实际上将它 扩展为:DBGrid1->SetOptions(DBGrid1->FOptions >> dgEditing); 实际上首先执行 DBGrid1->FOptions >> dgEditing,此时它改变的就是 DBGrid1->FOptions 的值,然 后将 DBGrid1->FOptions 作为参数,去执行函数SetOptions的代码。这样在这个函数 SetOptions 中,参数Value的值就等于原来的FOptions,所以就会不执行后面的代码, 造成了属性Options的值改变了,但是真正的效果却没有实现。此时就一定要使用一个 临时变量才可以,比如: TDBGridOptions Options = DBGrid1->Options; DBGrid1->Options = Options >> dgEditing; 下面再看看TDBNavigator的函数SetVisible的源代码: procedure TDBNavigator.SetVisible(Value: TButtonSet); var I: TNavigateBtn; W,H: Integer; begin W := Width; H := Height; FVisibleButtons := Value; for I := Low(Buttons) to High(Buttons) do Buttons[I].Visible := I in FVisibleButtons; SetSize(W, H); if (W <> Width) or (H <> Height) then inherited SetBounds (Left, Top, W, H); Invalidate; end; 这儿,程序没有检查参数Value的值是否和原来的值FVisibleButtons是否相同,所以上面 上面的回复中的写法就没有问题。所以在BCB里,给属性赋值时,有时是需要小心的。使用 临时变量的写法,总是可以的。而上面一个回复中的写法,有时可以有时却不可以。
Delphi和BCB中属性设置问题
最新推荐文章于 2020-09-13 09:26:44 发布