2009-11-03 42 views
5

Ứng dụng của chúng tôi được sử dụng để sử dụng một biểu mẫu cơ sở chung mà tất cả các biểu mẫu có nghĩa là kế thừa từ đó. Tôi muốn loại bỏ nó vì một số lý do, từ sự cần thiết đến cảnh sát mà mọi người đều sử dụng nó để một số phiền toái liên quan đến việc thực hiện VFI của Delphi. Nó chỉ ra rằng phần lớn các tính năng nó cung cấp có thể được thực hiện theo cách khác, đáng tin cậy hơn.Cách định vị biểu mẫu trước khi biểu mẫu hiển thị?

Điều mà tôi không chắc chắn, tự động định vị tất cả các biểu mẫu ở chính giữa người gọi của họ. Vì vậy, nếu tôi mở Hộp thoại A từ biểu mẫu chính của tôi, nó sẽ được đặt ở giữa biểu mẫu chính. Và nếu tôi mở Hộp thoại B từ Hộp thoại A, nó sẽ được đặt trên trung tâm của Hộp thoại A và cứ thế.

Chúng tôi đã từng xử lý tất cả điều này bằng cách đặt thuộc tính Vị trí của biểu mẫu cơ sở thành poOwnerFormCenter và nó hoạt động rất tốt. Nhưng làm cách nào để làm điều này trên toàn ứng dụng?

Tôi đã nghĩ đến việc sử dụng Screen.OnActiveFormChange, nhưng tôi nghĩ điều này xảy ra mỗi khi biểu mẫu nhận được tiêu điểm. Tôi cũng nghĩ đến việc sử dụng Application.OnModalBegin nhưng dường như không có cách nào rõ ràng để tìm thấy biểu mẫu tại thời điểm này được gọi.

Có ai đã thử điều này không?

Trả lời

5

Vâng, rõ ràng là hình thức thừa kế được cung cấp để giải quyết chính xác sự cố bạn đang cố giải quyết. Bất kỳ giải pháp có lẽ sẽ gió lên bắt chước hình thức thừa kế một cách nào đó.

Bạn có thể làm điều gì đó đơn giản như tìm kiếm trên toàn bộ mã của bạn cho "= class (TForm)" và thay thế lớp TForm bằng biểu mẫu cơ sở hiện tại của bạn hoặc một lớp biểu mẫu cơ sở mới, đơn giản chỉ với chức năng bạn cần?

Nếu không, bạn có thể cố gắng sửa đổi lớp TForm gốc để có hành vi định vị bạn muốn. Rõ ràng, việc sửa đổi các lớp được cung cấp là một chút ở phía nguy hiểm.

+1

+1 Tôi đã thoát khỏi căn cứ bởi vì mọi người không sử dụng nó và nó là một nỗi đau để cảnh sát nó. Vì vậy, tôi thực sự muốn lỗi logic của bạn ở đây, nhưng bạn nói đúng. Tôi vẫn không thể tìm thấy một cách đáng tin cậy để chăm sóc một hoặc hai yêu cầu mà không có cơ sở, vì vậy tôi đoán tôi sẽ phải đưa nó trở lại. Tôi chắc chắn nghĩ rằng tôi nên bỏ qua phần trực quan của thừa kế, bởi vì điều đó chỉ không hoạt động tốt. –

+0

Tôi không chắc chắn, nhưng có thể là IDE Delphi có thể được cấu hình để ít nhất hỗ trợ bạn trong việc đánh giá lớp mà các biểu mẫu mới được dựa trên. –

0

Nếu không biết nhiều hơn về ứng dụng của bạn, tôi khuyên bạn nên thêm mã định vị vào từng biểu mẫu riêng lẻ - ưu điểm của việc không có lớp cơ sở là dễ dàng hơn để có một số biểu mẫu nhất định. nó giữ tất cả logic của một hình thức với nhau ở một nơi.

+0

Sự cố ở đây là tỷ lệ. Chúng tôi có một vài trăm gói, hầu hết có chứa một số hình thức.Lớp cơ sở là (tôi nghĩ) một nỗ lực để đảm bảo tất cả các hình thức hành xử một cách nhất quán, nhưng khi những năm trôi qua và mọi người đến và đi, cơ sở không được sử dụng nhất quán. Tôi đang cố thực thi sự nhất quán này. –

4

Nếu bạn sẽ không đi với một biểu mẫu cơ sở chung, thì tôi khuyên bạn nên đặt thành phần không trực quan trên mỗi biểu mẫu. Thành phần đó có thể tiêm các hành vi mà bạn muốn vào biểu mẫu cơ sở. Nếu bạn muốn có các hành vi khác nhau khác nhau trên các biểu mẫu khác nhau thì hãy cung cấp cho thành phần của bạn một thuộc tính vai trò xác định vai trò của biểu mẫu nào và sau đó có thể tiêm các đặc điểm khác nhau dựa trên vai trò đó.

BTW, bạn cũng có thể có kế thừa hình thức không trực quan, là phương pháp ưa thích của tôi trong việc tạo lớp cơ sở chung cho tất cả các biểu mẫu. Nó cũng có lợi thế là thêm thuộc tính vào biểu mẫu, và sau đó dựa trên các thuộc tính đó, bạn có thể thay đổi vai trò hoặc hành vi của biểu mẫu.

0

Tôi thường sử dụng sự kiện FormShow cho việc này, sử dụng thủ tục SetBounds(). Với các điều khiển không dạng khác, bạn có thể thực hiện điều tương tự bằng cách ghi đè thông báo CMShowing.

+0

Xem nhận xét của tôi về câu trả lời của Kragen về quy mô của dự án. Nếu tôi không thể cảnh sát việc sử dụng một lớp cơ sở chung một cách hiệu quả, bất cứ điều gì đòi hỏi một sự thay đổi cho mỗi hình thức đều chết trong nước. Trong các dự án nhỏ hơn, bạn đúng tất nhiên. –

0

Tôi lấy ý tưởng của bạn về OnModalBegin và chạy với nó. Sau đây là một "Hack", nhưng nó có vẻ làm việc. Để kiểm tra, chỉ cần kéo xung quanh biểu mẫu và nhấp vào nút.

procedure TMainForm.Button1Click(Sender: TObject); 
var 
    mForm: TForm; 
begin 
    mForm := TForm.create(self); 
    mform.width := 300; 
    mform.height := 300; 
    mForm.ShowModal; 
    mForm.Free; 
end; 

procedure TMainForm.FormCreate(Sender: TObject); 
begin 
    application.OnModalBegin := modalbegin; 
end; 

procedure TMainForm.FormShow(Sender: TObject); 
begin 
    if Screen.FormCount>1 then begin 
    screen.forms[Screen.FormCount-1].left := round((screen.forms[Screen.FormCount-2].left + screen.forms[Screen.FormCount-2].width/2) - screen.forms[Screen.FormCount-1].width/2); 
    screen.forms[Screen.FormCount-1].top := round((screen.forms[Screen.FormCount-2].top + screen.forms[Screen.FormCount-2].height/2) - screen.forms[Screen.FormCount-1].height/2); 
    application.processmessages; 
    screen.forms[Screen.FormCount-1].Caption := inttostr(screen.forms[Screen.FormCount-1].top)+','+inttostr(screen.forms[Screen.FormCount-1].left); 
    end; 
end; 

procedure TMainForm.ModalBegin(Sender: TObject); 
begin 
    if Screen.FormCount>=0 then 
    screen.forms[Screen.FormCount-1].OnShow := FormShow; 
end; 
Các vấn đề liên quan