我创建了一个列表框,并使用它来添加和删除/加载并将项目保存到一个非常好的文件中。但是当我尝试在另一个单元上使用列表框时,我收到一个错误:未声明的标识符。
MainUnit
下方的第一个单元是我尝试使用列表框并获取错误未声明标识符的位置。 MainUnit
下面是ManageUsersUnit
,这是使用和创建列表框的单位。所有代码都与ManageusersUnit
上的列表框一起使用,但不适用于任何其他单元。
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus, ExtCtrls;
implementation
uses AddTenantUnit, HomeUnit, MainMenuUnit;
{$R *.dfm}
{ the error im getting is in this procedure}
procedure TMainForm.FormCreate(Sender: TObject);.
begin
if fileExists('Newuser.dat')
then
begin
UserListBox.Items.LoadFromFile('Newuser.dat');
end
{endif};
end;
unit ManageUsersUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, MainUnit, StdCtrls, Menus, ComCtrls;
type
TManageUsersForm = class(TForm)
AddUserButton: TButton;
RemoveUserButton: TButton;
ChangeUsernameButton: TButton;
ChangePasswordButton: TButton;
HomeButton: TButton;
UserListBox: TListBox;
UsernameEdit: TEdit;
SaveButton: TButton;
PasswordEdit: TEdit;
SubText1Label: TLabel;
SubText2Label: TLabel;
PassListBox: TListBox;
Button1: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
var
ManageUsersForm: TManageUsersForm;
implementation
uses PassWord, AddUserUnit, HomeUnit;
{$R *.dfm}
procedure TManageUsersForm.HomeButtonClick(Sender: TObject);
begin
HomeForm.show;
ManageUsersForm.Close;
end;
//Add UserName
procedure TManageUsersForm.AddUserButtonClick(Sender: TObject);
var
i : integer;
Found : Boolean;
AddUser : string;
begin
{ManageUsersForm.close;
AddUserForm.ShowModal; }
Found := false;
AddUser := UsernameEdit.Text;
i := 0;
while i < userlistbox.Items.Count do
begin
if (UpperCase(AddUser) = Uppercase(userlistbox.Items[i]))
then
Found := True;
inc(i);
end;
{endhwile};
if Found = False then
begin
userlistbox.Items.Add(AddUser);
UsernameEdit.Text := '';
showMessage(AddUser + ' added');
end
else
showMessage(AddUser + ' is already present.');
{endif};
end;
procedure TManageUsersForm.RemoveUserButtonClick(Sender: TObject);
var
deleted : string;
begin
with UserListBox do
begin
if ItemIndex = -1
then
showMessage('You must select a User first.')
else
begin
Deleted := Items.Strings[ItemIndex];
Items.Delete(ItemIndex);
showMessage(Deleted + ' deleted');
end;
{endif};
end;
end;
procedure TManageUsersForm.Button1Click(Sender: TObject);
var
i : integer;
Found : Boolean;
check : string;
begin
check := PasswordEdit.Text;
Found := false;
i := 0;
while i < userlistbox.Items.Count do
begin
if (UpperCase(check) = Uppercase(userlistbox.Items[i]))
then
Found := True;
inc(i);
end;
{endhwile};
if Found = False
then
begin
showMessage(check + ' Incorrect Username');
end
else
showMessage(' well done in file :).');
{endif};
end;
procedure TManageUsersForm.SaveButtonClick(Sender: TObject);
begin
assignfile (userFile,'Newuser.dat');
UserListbox.Items.SaveToFile('Newuser.dat');
showMessage('Saved to file');
end;
procedure TManageUsersForm.FormCreate(Sender: TObject);
begin
if fileExists('Newuser.dat')
then
begin
UserListBox.Items.LoadFromFile('Newuser.dat');
end
{endif};
end;
procedure TManageUsersForm.TestBtnClick(Sender: TObject);
begin
AddUserForm.ShowModal;
end;
end.
答案 0 :(得分:4)
您的MainUnit
需要使用ManageUsersUnit
单元。如果对该另一个单元中的表单的唯一引用位于implementation
部分,则将其添加到那里的uses
子句中。作为一般规则,如果绝对必要,您应该只添加interface uses子句。
unit MainUnit;
/// ...
implementation
uses AddTenantUnit, HomeUnit, MainMenuUnit, ManageUsersUnit;
您的代码然后直接引用UserListBox
,但此引用是TManageUsersForm
类的成员变量,因此您必须首先在访问该实例的成员之前标识该类的实例。
在这种情况下,您似乎已经有一个公共实例,您可能打算使用它:ManageUsersForm
因此,将文件数据加载到列表中的代码应为:
ManageUsersForm.UserListBox.Items.LoadFromFile('Newuser.dat');
这将解决您的直接问题。但是,这种方法存在很多问题。
MainUnit 假设 ManageUsersForm 是有效的现有表单实例。如果表单在项目中设置为 AutoCreate ,那么这可能有效,但是因为它会使您的代码生效 易于改变表单的创建方式。
MainUnit 对 ManageUsers 表单的某些行为负有不当责任。如果ManageUsers表单真正管理用户,那么这应该包括用户与文件本身的持久性。
MainUnit 高度依赖于 ManageUsers 表单的内部详细信息。我们说这是“紧密耦合”。如果ManageUsers表单被修改为使用例如列表视图的网格来呈现用户,则MainUnit代码将会中断,因为它依赖于用户列表特别是列表框的深入了解。
由于VCL的工作方式,Delphi中表单上的用户界面控件可公开访问,但您应将其视为私有(或者,最多保护强>)。您的 ManageUsers 表单应为其提供给“外部世界”的功能提供公共界面,该“外部世界”处理用户数据。
表单的用户界面元素(包括任何事件处理程序)不应该引用表单本身之外(如果使用表单类的OO层次结构,则不应引用子代表单类)。