用户只读权限该如何设计:是控制数据集(ado系列)还是控制编辑控件(dbedit,cxgrid),
ado系列组件除了adotable有readonly属性外,其它组件(adoquery、adostoredproc)都没有readonly属性具体该如何控制,那种方法比较合理、方便谢谢先!

解决方案 »

  1.   

    建议使用Tfield的只读属性。这个比设置编辑控件的只读属性要好,因为这个与UI元素分离了,可以使用任意的数据感知控件,而不必一一的去设置它们的只读与否。
      

  2.   

    具体是这样:
    菜单是根据登录用户的权限动态创建的,
    但有其它用户可以察看和查询,但不允许添加、删除、编辑,
    我的权限表里有一个[是否只读 bit]字段,
    我想当用户打开窗体时判断当前窗体对当前用户是否为只读,
    如果是应该怎么做,是控制数据集(ado系列)还是控制编辑控件(dbedit,cxgrid), 尊敬的chris_mao:能否按您的思路帮我写一段示例代码!我的理解:
    首先在设计时是不是应该先给ADO系列组件创建固定字段,
    然后在窗体打开时循环所有数据集字段并设定字段的只读属性?
      

  3.   

    不用创建固定字段。
    假设所有的窗体都是从一个自己写的基类窗体继承而来,在这个基类窗体中声明一下虚拟方法,提供默认的操作,同时也允许子类对其进行扩展或改写(这就是为什么要声明为虚方法)  TBaseForm = class(TForm)
      private
        { Private declarations }
        ......
        procedure SetDataSetFieldReadOnly(ADataSet: TDataSet; Value: Boolean);
        ......
      protected
        ......
        procedure InitialForm; virtual;
        procedure SetDataSetReadOnly(Value: Boolean); virtual;
        ......
      public
        { Public declarations }
        ......
      end;procedure TBaseForm.InitialForm;
    begin
      //对窗体进行初始化工作
      ......
      SetDataSetReadOnly(True);
      ......
    end;procedure TBaseForm.SetDataSetFieldReadOnly(ADataSet: TDataSet; Value: Boolean);
    var
      i: Integer;
    begin
      for i := 0 to ADataSet.FieldCount - 1 do begin
        if ADataSet.Fields[i].FieldKind = fkData then
          ADataSet.Fields[i].ReadOnly := Value;
      end;
    end;procedure TBaseForm.SetDataSetReadOnly(Value: Boolean);
    var
      i: Integer;
    begin
      for i := 0 to ComponentCount - 1 do begin
        if Components[i].InheritsFrom(TDataSet) then
          SetDataSetFieldReadOnly(TDataSet(Components[i]), Value);
      end;
    end;procedure TBaseForm.Create(Sender:TObject);
    begin
      ......
      InitialForm;
      ......
    end;
      

  4.   

    SetDataSetReadOnly的参数是依据你得到的权限设定,我这里假设为True
      

  5.   

    非常感谢chris_mao!遗憾的是,我太菜,目前还无法完全理解您的代码(什么基类、虚拟方法、子类),能否直接告诉我这些代码应该写在那里,如何在每个窗体调用,当然!您愿意的话!
      

  6.   

    谢谢chris_mao老师:有些明白您的代码了,已基本实现,但插入和删除健没有屏蔽,
    还有,如果用户试图编辑的话,可否弹出一个对话框,告诉用户权限不足。
    谢谢!
      

  7.   

    从用户心理上来讲,如果用户没有权限使用的功能,最好不要给他提供入口(如菜单,或是功能按钮等),因为你给他提供了他却无法使用。
    建议做法:依据其权限显示出其可以使用的菜单和功能按钮,确保用户登录后,看到的所有功能都是对他开发的(无权限使用的他看不到)。针对你所说的删除和插入这两个功能,就可以在初始化窗体时将其隐藏起来。  TBaseForm = class(TForm)
      private
        { Private declarations }
        ......
        procedure SetDataSetFieldReadOnly(ADataSet: TDataSet; Value: Boolean);
        ......
      protected
        ......
        procedure InitialForm; virtual;
        procedure SetDataSetReadOnly(Value: Boolean); virtual;
        procedure InitialPermission; virtual;
        ......
      public
        { Public declarations }
        ......
      end;procedure TBaseForm.InitialPermission;
    begin
      //此处使用了Action对象,你可以依据用户权限设置其Enabled和Visible属性
      .........
      actDelete.Visible := False;
      actDelete.Enabled := False;
      actInsert.Visible := False;
      actInsert.Enabled := False;
      ............
    end;
      

  8.   

    那就要调整这些方法了,而且你需要在每个编辑窗体中都要调用这些方法,重复的代码太多。
    其实继承没你想的那么难。你建好一个窗体后,然后点新建,在弹出的窗体中选择你工程的那个标签(如Project1),然后选择做为父类的窗体图标,点OK即可。
      

  9.   

    经过这两天的学习,特别是看了您的[Delphi中的继承机制]一文,对继承有点明白了,但还是有些迷糊,
    我准备尝试使用继承,本来想加您为好友,但看了您的blog,发现您“太高了”了,我和
    您根本不是一个档次,所以就算了。真的很谢谢您...