2009-03-24 30 views
33

Tôi tạo ra một lớp chung cơ sở cho một WinForm UserControl:lớp cơ sở chung cho WinForm UserControl

public partial class BaseUserControl<T> : UserControl 
{ 
    public virtual void MyMethod<T>() 
    { 
     // some base stuff here 
    } 
} 

Và một usercontrol dựa trên rằng:

public partial class MyControl : BaseUserControl<SomeClass> 
{ 
    public override void MyMethod<SomeClass>() 
    { 
     // some specific stuff here 
     base.MyMethod<SomeClass>(); 
    } 
} 

Nó hoạt động tốt, nhưng MyControl không thể chỉnh sửa trong VisualStudio Designer, bởi vì nó nói nó không thể tải lớp cơ sở. Tôi đã cố gắng để xác định một lớp BaseUserControl, không chung chung, hy vọng nó sẽ tải nó, nhưng lừa dường như không hoạt động.

Tôi đã có một cách giải quyết: xác định một giao diện, IMyInterface <T>, và sau đó tạo ra sự kiểm soát của tôi như

public partial class MyControl : UserControl, IMyInterface<SomeClass> 

Nhưng tôi đã làm mất cơ sở phương pháp của tôi ảo (không phải là một vấn đề lớn, nhưng vẫn còn ...).

Có cách nào để tạo một lớp chung chung cho UserControl, với khả năng chỉnh sửa nó trong VisualStudio Designer không?

+0

bạn không cần phải mất cơ sở phương pháp ảo của bạn, chứa lớp implementor thay vì kế thừa từ nó. – Robocide

Trả lời

34

Chúng tôi đang làm điều tương tự và chúng tôi làm việc xung quanh bằng cách chuyên một lớp học đầu tiên và xuất phát từ lớp học chuyên ngành. Sử dụng mã từ ví dụ của bạn điều này có nghĩa gì đó như:

public partial class UserControl : UserControlDesignable 
{ 

... 
} 
public class UserControlDesignable : BaseUserControl<Someclass> { } 

Các nhà thiết kế vẫn còn hành động flaky đôi khi - nhưng phần lớn thời gian nó hoạt động.

+0

Trong khi giải pháp khác, lưu ý rằng điều này phải nằm trong tệp phụ và nếu cơ sở trừu tượng và người dùng đang sử dụng thuộc tính nhà cung cấp loại tùy chỉnh (như được đề cập trong các bài đăng khác trên trang web này), nó sẽ phải đi vào mỗi lớp –

+0

vẫn là giải pháp làm việc duy nhất trong VS2015. Không có hỗ trợ gốc được thêm bởi MS ...:-( –

14

Bạn sẽ phải lừa người thiết kế bằng cách thêm một lớp 'thông thường' kế thừa từ biểu mẫu cơ sở chung của bạn. Biểu mẫu có thể thiết kế của bạn sau đó sẽ được kế thừa từ lớp này. Các định nghĩa 2 lớp sau đây là như vậy trong cùng một tệp. Bạn sẽ phải đảm bảo rằng lớp kế thừa từ điều khiển người dùng cơ sở chung, là lớp cuối cùng trong tệp.

public MyForm : EditableCustomerForm 
{} 

public EditableCustomerForm : GenericForm<Customer> 
{} 

Nhà thiết kế sẽ hiển thị lớp đầu tiên trong tệp mã mà ứng dụng gặp phải.

+0

Ý tưởng tuyệt vời, nhưng lưu ý rằng vì lớp cơ sở phải được biên dịch trước khi nhà thiết kế có thể sử dụng nó, điều đó có nghĩa là đối với bất kỳ thay đổi nào đối với lớp EditableCustomerForm, nó sẽ phải xây dựng lại để nhà thiết kế có ảnh hưởng, nhà thiết kế có thể sẽ chỉ hoạt động trên lớp MyForm –

3

Điều này dường như là một lỗi trong Visual studio.

Bằng cách đào sâu vào khuôn khổ (trên thực tế bằng cách thêm một RootDesignerSerializer với một kiểu tùy biến bắt nguồn từ CodeDomSerializer và trọng phương pháp serialize), tôi đã có thể chứng minh rằng các nhà cung cấp VS Mã Dom là thực sự phân tích sai các lớp generic, và thay vào đó xem xét nó như là một lớp chung chung nó đang xem xét nó như là một lớp học thường xuyên với tên class<T>, trong đó Type.GetType() tất nhiên có thể không tìm thấy.

Tôi vẫn đang tìm cách giải quyết nó, nhưng trong thời gian trung bình, người ta có thể sử dụng các giải pháp trên.

Có một báo cáo lỗi Microsoft.Connect vào nó, hãy bỏ phiếu về nó ở https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-generic-form

Các vấn đề liên quan