Delphi和BCB中属性设置问题

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里,给属性赋值时,有时是需要小心的。使用
  临时变量的写法,总是可以的。而上面一个回复中的写法,有时可以有时却不可以。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值