تجنب الحوار المتداول في دلفي و /أو C++
-
08-07-2019 - |
سؤال
أنا غالبا ما تحتاج إلى تصميم مربع حوار في دلفي/C++Builder التي تسمح خصائص مختلفة من كائن إلى تعديل التعليمات البرمجية لاستخدام عادة ما تبدو مثل هذا.
Dialog.Edit1.Text := MyObject.Username;
Dialog.Edit2.Text := MyObject.Password;
// ... many more of the same
if (Dialog.ShowModal = mrOk)
begin
MyObject.Username := Dialog.Edit1.Text;
MyObject.Password := Dialog.Edit2.Text;
// ... again, many more of the same
end;
كما أنني في كثير من الأحيان تحتاج مماثلة رمز تسخير الكائنات من/xml/ini files/أيا كان.
هل هناك أي التعابير المشتركة أو تقنيات تجنب هذا النوع من بسيطة ولكن بالتكرار الرمز ؟
المحلول
وكذلك، وهو الأمر الذي أشعر لا تقدر بثمن تماما هو GExperts المعالج المساعد "بيان عكسي" الذي يتم استدعاؤه بعد تركيب GExperts عن طريق الضغط على Shift + ALT + R
وماذا يفعل والتبديل تلقائيا التعيينات في جميع أنحاء لكتلة تسليط الضوء عليها. على سبيل المثال:
edit1.text := dbfield.asString;
ويصبح
dbField.asString := edit1.text;
وليس بالضبط ما كنت تبحث عن، ولكن الوقت المدخر كبيرة عندما يكون لديك عدد كبير من المهام.
نصائح أخرى
وهنا الاختلاف بلدي في هذا الشأن. ما فعلته، بعد أن حصلت سئمت نفس الرمز المتكرر، وكان لتسمية جميع مربعات التحرير وفقا لأسماء عقدة XML أردت، ثم أعاد حول مكونات والانتاج قيمهم. يجب أن يكون الرمز XML واضحة، وليس لدي سوى تحرير ومربع، ولكن يجب أن تكون قادرا على رؤية هذه الفكرة.
procedure TfrmFTPSetup.LoadFromXML(szFileName : string);
var
xComponent : TComponent;
nLoop : Integer;
xMainNode : TXmlNode;
xDocument : TNativeXml;
begin
inherited;
xDocument := TNativeXml.Create;
try
xDocument.LoadFromFile(szFileName);
xMainNode := xml_ChildNodeByName(xDocument.Root, 'options');
for nLoop := 0 to ComponentCount - 1 do
begin
xComponent := Components[nLoop];
if xComponent is TRzCustomEdit then
begin
(xComponent as TRzCustomEdit).Text := xMainNode.AttributeByName[xComponent.Name];
end;
if xComponent is TRzCheckBox then
begin
(xComponent as TRzCheckBox).Checked := xml_X2Boolean(xMainNode.AttributeByName[xComponent.Name], false);
end;
end;
finally
FreeAndNil(xDocument);
end;
end;
procedure TfrmFTPSetup.SaveToXML(szFileName : string);
var
xComponent : TComponent;
nLoop : Integer;
xMainNode : TXmlNode;
xDocument : TNativeXml;
begin
inherited;
xDocument := TNativeXml.CreateName('ftpcontrol');
try
xMainNode := xml_ChildNodeByNameCreate(xDocument.Root, 'options');
for nLoop := 0 to ComponentCount - 1 do
begin
xComponent := Components[nLoop];
if xComponent is TRzCustomEdit then
begin
xMainNode.AttributeByName[xComponent.Name] := (xComponent as TRzCustomEdit).Text;
end;
if xComponent is TRzCheckBox then
begin
xMainNode.AttributeByName[xComponent.Name] := xml_Boolean2X((xComponent as TRzCheckBox).Checked);
end;
end;
xDocument.XmlFormat := xfReadable;
xDocument.SaveToFile(szFileName);
finally
FreeAndNil(xDocument);
end;
end;
إنه لا يعتبر ممارسة جيدة للوصول إلى خصائص مكونات بصرية على شكل.ويعتبر الأفضل أن يكون منفصلة خصائص.في المثال أعلاه سيكون لديك اسم المستخدم وكلمة المرور خصائص مع الحصول على مجموعة الأساليب.
على سبيل المثال:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
private
function GetPassword: string;
function GetUsername: string;
procedure SetPassword(const Value: string);
procedure SetUsername(const Value: string);
public
property Password: string read GetPassword write SetPassword;
property Username: string read GetUsername write SetUsername;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TForm1.GetPassword: string;
begin
Result := Edit2.Text;
end;
function TForm1.GetUsername: string;
begin
Result := Edit1.Text;
end;
procedure TForm1.SetPassword(const Value: string);
begin
Edit2.Text := Value;
end;
procedure TForm1.SetUsername(const Value: string);
begin
Edit1.Text := Value;
end;
end.
هذا يعني أنه يمكنك تغيير مكونات بصرية على شكل دون أن تؤثر على رمز الدعوة.
سيكون هناك خيار آخر لتمرير وجوه الملكية إلى الحوار;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TUserObject = class(TObject)
private
FPassword: string;
FUsername: string;
public
property Password: string read FPassword write FPassword;
property Username: string read FUsername write FUsername;
end;
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
btnOK: TButton;
procedure btnOKClick(Sender: TObject);
private
FUserObject: TUserObject;
procedure SetUserObject(const Value: Integer);
public
property UserObject: Integer read FUserObject write SetUserObject;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnOKClick(Sender: TObject);
begin
FUserObject.Username := Edit1.Text;
FUserObject.Password := Edit2.Text;
ModalResult := mrOK;
end;
procedure TForm1.SetUserObject(const Value: Integer);
begin
FUserObject := Value;
Edit1.Text := FUserObject.Username;
Edit2.Text := FUserObject.Password;
end;
end.
على أمل أن يساعد.
ودلفي على الاقل ان يكون 'مع'، على الرغم من أنه لا يحل المشكلة تماما.
if (Dialog.ShowModal = mrOk)
begin
with MyObject do
begin
Username := Dialog.Edit1.Text;
Password := Dialog.Edit2.Text;
// ... again, many more of the same
end;
end;
وباني AFAIK لا يملك شيئا على حد سواء.
والضوابط الملزمة لبيانات يعمل بشكل جيد في دلفي، ولكن للأسف فقط عندما يتواجد هذه البيانات في سليل TDataSet. هل يمكن أن يكتب سليل TDataSet يستخدم كائن لتخزين البيانات، واتضح أن هذا شيء واحد موجود بالفعل. انظر الرابط أدناه ... هذا التطبيق يبدو أن تعمل فقط مع مجموعات من الكائنات (TCollection أو TObjectList)، وليس الأشياء واحدة.
http://www.torry.net/pages.php؟id=563 - ابحث في الصفحة عن "مجموعة البيانات كائن التقط"
وليس لدي أي تجربة شخصية مع هذا، ولكن سيكون من المفيد جدا اذا كان يعمل وخاصة إذا كانت ستعمل أيضا مع مثيلات الكائن واحدة، مثل خاصية على حدة البيانات ...
وابحث عن " الوسيط نمط ". إنها نمط تصميم صندوق جلوبل القناص، وفي كتابهما للصندوق جلوبل القناص في الواقع تحفيز هذا النمط تصميم وضعا يشبه إلى حد ما ما كنت تصف هنا. ويهدف إلى حل مشكلة مختلفة - اقتران - ولكن اعتقد ان لديك هذه المشكلة على أية حال جدا
وباختصار، فإن الفكرة هي خلق وسيط الحوار، كائن الإضافي الذي يجلس في بين جميع الحاجيات الحوار. لا القطعة يعرف عن أي القطعة الأخرى، ولكن كل القطعة هل يعرف الوسيط. الوسيط يعرف كل الحاجيات. عندما تتغير القطعة واحدة فإنه يبلغ الوسيط. الوسيط ثم بإعلام الحاجيات ذات الصلة حول هذا الموضوع. على سبيل المثال، عند النقر فوق موافق الوسيط قد تبلغ الحاجيات الأخرى حول هذا الحدث.
وهذه الطريقة في كل الحاجيات يعتني الأحداث والإجراءات المتصلة نفسها فقط. الوسيط يعتني التفاعل بين جميع الحاجيات، لذلك يتم تقسيم كل هذا "النمطي" مدونة على كل الحاجيات، و "بقايا" والذي هو عالمي لجميع الحاجيات هي التفاعل، وهذا هو مسؤولية الوسيط.