Có nên sử dụng các điều khiển người dùng để cấu trúc các biểu mẫu WPF ngay cả khi các điều khiển người dùng này chỉ được sử dụng một lần không?


8

Tôi phát triển ứng dụng WPF bằng MVVM và tôi đang học cách làm mọi thứ tốt nhất.

Tôi có một biểu mẫu WPF với các bộ chọn, hai danh sách với các trường tìm kiếm và một số yếu tố khác. Hiện tại tất cả chỉ ở một dạng và nó hoạt động. Nhưng đến bây giờ VM cho hình thức đó có hơn 800 dòng và nó vẫn chưa hoàn thành.

Tôi muốn cấu trúc biểu mẫu này và mã tốt hơn. Tôi nghĩ về các vùng, tệp với các lớp một phần và điều khiển người dùng. Tôi nghĩ rằng điều khiển người dùng sẽ là tốt nhất bởi vì họ gói gọn một vài điều khiển và logic. Nếu tôi sử dụng các điều khiển của người dùng thì số lượng mã trong cửa sổ đó và VM sẽ giảm đáng kể.

Để làm điều này đúng, tôi làm việc thông qua cuốn sách "Pro WPF 4.5 In C # 4th Edition", Chương 18 - Các yếu tố tùy chỉnh và mẫu ColorPickerUserControl. Mẫu này là về một bộ chọn màu với ba thanh trượt và nó có 150 dòng mã.

Tôi nghĩ rằng tôi hiểu cách thức hoạt động của nó nhưng đối với tôi, việc tạo ra các điều khiển người dùng, ngay cả với chức năng rất hạn chế như trong mẫu đó, là rất nhiều công việc . Nếu tôi sử dụng các điều khiển này nhiều lần thì tôi hiểu sẽ hợp lý khi làm điều này. Nhưng nếu tôi chỉ sử dụng các điều khiển một lần và tôi chỉ làm điều này để cấu trúc biểu mẫu của mình thì đây có vẻ là rất nhiều công việc để kiếm được ít tiền.

Câu hỏi của tôi là: Có nên sử dụng các điều khiển người dùng để cấu trúc các biểu mẫu ngay cả khi các điều khiển người dùng này chỉ được sử dụng một lần không? Nếu không, có một sự thay thế tốt hơn?

Chỉnh sửa (không cần đọc, chỉ cần thêm thông tin): Cho đến bây giờ tôi không viết bất kỳ chi tiết nào vì tôi muốn tìm hiểu về nguyên tắc nhưng sau khi đọc câu trả lời thú vị của 17, 26, đây là một số chi tiết: Hình thức này là chọn tiêu đề nhạc.

  • Nhóm A: (có thể kiểm soát người dùng A) là về loại lựa chọn như chọn theo nghệ sĩ hoặc album, có hoặc không có video, có thể năm xuất bản, v.v.

  • Nhóm B: Danh sách này chứa tên nghệ sĩ được lọc theo tiêu chí trong A. Người dùng có thể lọc danh sách tức là chỉ hiển thị tên nghệ sĩ có chứa "top".

  • Nhóm C: Danh sách này hiển thị các tiêu đề từ nghệ sĩ được chọn trong B cũng sử dụng tiêu chí từ A (tức là âm thanh hoặc video). Nó có thể được lọc tương tự như B tức là chỉ các tiêu đề có chứa "bạn".

Hầu hết logic xảy ra trong VM (DataContext của biểu mẫu). Các danh sách từ A và B đến từ cơ sở dữ liệu. Các danh sách được lọc và chuẩn bị để trình bày (tức là nhiều tiêu đề có cùng tên nhưng trong các album khác nhau). Người dùng chọn một tiêu đề trong Danh sách C bằng cách nhấp đúp hoặc sử dụng kéo và thả vào một biểu mẫu WPF khác.

Những gì tôi muốn: Tôi muốn mã có thể đọc được để tôi có thể dễ dàng sửa đổi nó. Nếu tôi muốn thêm tức là một bộ lọc khác, hãy nói rằng chỉ hiển thị các nghệ sĩ nữ thì sẽ tốt hơn nếu tôi có thể đi đến kiểm soát người dùng A và thêm các hộp kiểm cho các nghệ sĩ nam và / hoặc nữ.

XAML ở dạng hiện tại không có vấn đề gì, nó có cấu trúc tốt. Nhưng VM có mã cho tất cả các bên trên. Một số thứ nằm trong hàm tạo, một số trong phần lệnh, một số thuộc tính và các trường sao lưu. Tôi vẫn có thể tìm thấy mọi thứ bây giờ nhưng tôi nghĩ sẽ tốt hơn nếu mã sẽ có cấu trúc hơn. Đây là lý do tại sao tôi nghĩ về Kiểm soát người dùng.

Tôi cố gắng theo dõi MVVM bởi vì tôi nghĩ logic đằng sau nó có rất nhiều ý nghĩa. Nhưng tôi không phải là tín đồ cuồng nhiệt của bất kỳ thực hành lý thuyết nào. Tức là nếu tôi có thể làm gì đó trong 5 dòng CodeBehind hoặc trong 50 dòng trong VM tôi sẽ làm điều đó trong CodeBehind. Câu hỏi của tôi là về nguyên tắc làm thế nào để tạo các biểu mẫu có cấu trúc trong WPF. Biểu mẫu tôi mô tả ở trên là một ví dụ hay nhưng câu trả lời không nên tập trung vào một từ này mà là ý tưởng làm thế nào để cấu trúc các biểu mẫu WPF tức là có (hoặc không có) điều khiển người dùng.

Về lý do tại sao tôi nghĩ rằng các điều khiển của người dùng là rất nhiều công việc: Chúng có các thuộc tính phụ thuộc, các sự kiện được định tuyến, v.v ... Tất cả điều này đối với tôi phức tạp hơn nhiều so với các thuộc tính của Bình thường với các trường sao lưu và INotify. Nhưng có lẽ tôi chỉ phải làm quen với các thuộc tính phụ thuộc, các sự kiện được định tuyến, v.v.


Tôi hơi bối rối về lý do tại sao bạn nghĩ rằng việc kiểm soát người dùng là rất nhiều công việc. Ở dạng đơn giản nhất, UserControl chỉ là một thùng chứa. Bạn làm một cái như thế này : <UserControl> </UserControl>. Đó là nó.
Robert Harvey

Về chỉnh sửa của bạn: Điều khiển người dùng chỉ có các thuộc tính phụ thuộc, các sự kiện được định tuyến, v.v., nếu bạn quyết định đưa những thứ đó vào. Chúng không bắt buộc, bằng mọi cách.
Robert Harvey

@RobertHarvey: Vâng, tôi hiểu điều đó. Nhưng dường như "chức năng đầy đủ" với ràng buộc hai chiều, kích hoạt một cái gì đó ở dạng chính nếu một cái gì đó trong điều khiển người dùng bị thay đổi, v.v. chúng là cần thiết. Tôi nghĩ rằng mẫu trong cuốn sách mà tôi đề cập ở trên cho thấy mức độ cần thiết của chúng (không phải luôn luôn).
Edgar

Bạn sẽ vẫn không phải làm tất cả những điều đó mà không sử dụng Điều khiển người dùng chứ?
Robert Harvey

1
Nó cũng không có vẻ như ViewModel đang làm rất nhiều việc. Sắp xếp và lọc danh sách kết quả là một nhiệm vụ khá nhỏ đối với ViewModel. Có lẽ vấn đề không phải là những gì VM đang làm, nhưng cách nó được viết. Có lẽ có một số tính năng C # bạn có thể sử dụng để giảm kích thước mã. Hoặc có lẽ VM có thể được tái cấu trúc để thu nhỏ kích thước của nó.
17 26

Câu trả lời:


7

Hoàn toàn đồng ý. Đó là một ý tưởng tốt theo cùng một cách mà đó là một ý tưởng tốt để áp dụng phân tách các mối quan tâm trên các lớp để đặt mỗi mục riêng để thực hiện một nhiệm vụ duy nhất. Bạn có thể chỉ có một thể hiện của lớp đó, nhưng nó không quan trọng. Tối ưu hóa không phải là về hiệu suất chương trình mà về mặt tổ chức và "sức khỏe" tổng thể của chương trình.

Bạn muốn có thể quay lại chương trình của mình một ngày và không phải cuộn qua hàng trăm trang mã, ngay cả khi nó được đưa vào các vùng (sử dụng các vùng trên các lớp có nhiều mã giống như đặt son môi lên heo đường). Nếu một ngày nào đó bạn quyết định sử dụng nó ở một nơi khác, bạn có thể làm điều đó một cách duyên dáng và không gặp nhiều vấn đề.

Chỉ cần không tạo ra sự cám dỗ của việc cấp quyền kiểm soát người dùng cho biểu mẫu gốc. Nếu bạn làm theo cách này, hãy sử dụng các sự kiện để truyền đạt thông tin đến phụ huynh, với hình thức phụ huynh là người đăng ký.


Ngoài ra, khi bạn tạo một điều khiển tùy chỉnh, bạn có thể gói gọn một phần của logic trình bày mà nó chịu trách nhiệm, nếu được thực hiện đúng, sẽ lần lượt làm cho logic trình bày của bạn trong điều khiển chứa đơn giản hơn.
Filip Milovanović

"Hoàn toàn có" là một IMHO không phải là một câu trả lời hay khi nỗ lực tạo điều khiển người dùng cao như OP mô tả.
Doc Brown

1
Một VIewModel có một mối quan tâm duy nhất là phối hợp logic giao diện người dùng cho một tập hợp các điều khiển giao diện người dùng. Phá vỡ những điều này có thể là thách thức và thường không có ý nghĩa.
17 của 26 tháng

2
@DocBrown Câu hỏi yêu cầu ý kiến ​​về thực hành nói chung. Vì vậy, tôi nghĩ rằng câu trả lời của Neil là công bằng và là một ý kiến ​​trung thực. Không có câu trả lời tuyệt đối cho bất cứ điều gì, nhưng chúng tôi luôn có thể đề xuất một nơi nào đó để bắt đầu. IMHO nếu tôi được trả tiền để viết mã, tôi sẽ thực hiện đúng cách (khuyến nghị của Neil). Ngoài ra - nó thực sự có thể giúp làm điều này nếu bạn muốn sử dụng lại các điều khiển cho các dự án trong tương lai. Nhưng nếu tôi chỉ muốn chơi xung quanh hoặc tự làm một cái gì đó thì tôi sẽ làm điều đó nhanh hơn vì tôi đã bỏ lại đồ giặt.
Christopher

1
"Hoàn toàn có" là không chính xác. Câu trả lời đúng là "Nó phụ thuộc". Nó thêm chi phí và độ phức tạp để phân chia View / VM thành nhiều Chế độ xem / VM. Lợi ích cần phải vượt xa chi phí.
17 của 26 tháng

4

Đây là một câu hỏi thực sự khó trả lời mà không nhìn thấy mã thực tế. Bạn cũng đang trộn các thuật ngữ một chút. Điều khiển người dùng không phải là ánh xạ 1: 1 với ViewModels.

Điều khiển người dùng có một mục đích cụ thể trong cuộc sống: Chúng là một thành phần của nhiều thành phần UI được sử dụng như một đơn vị cùng nhau. Kiểm soát người dùng là phần phụ của Chế độ xem. Điều này rất khác với ViewModel, chứa logic mà View bị ràng buộc.

Có lẽ việc chia XAML của bạn thành nhiều điều khiển người dùng được điều khiển bởi một ViewModel duy nhất. Có lẽ sẽ hợp lý khi chia mã XAML và C # của bạn thành nhiều cặp View-VM. Có lẽ nó có ý nghĩa để chỉ để nó như bạn có nó bây giờ. Không thể nói mà không nhìn thấy mã trong câu hỏi.

Mục tiêu cuối cùng của bạn ở đây là gì? Là kích thước của mã khiến bạn thực sự đau đớn hay đây chỉ là để làm theo một số thực hành lý thuyết?

Bạn đang cố gắng giảm kích thước Lượt xem XAML hoặc kích thước của ViewModels C # của bạn? Đây là hai nhiệm vụ rất khác nhau trong thế giới MVVM của WPF.

800 dòng không phải là quá lớn đối với một VM hỗ trợ UI có bất kỳ loại phức tạp nào với nó. Phá vỡ một VM thường có thể gây ra nhiều vấn đề hơn nó giải quyết. ViewModels đưa ra quyết định như "vô hiệu hóa tính năng này khi danh sách khác này trống". Cố gắng tách ra loại quyết định đó trên nhiều thành phần thường không có ý nghĩa và sẽ chỉ làm tăng thêm độ phức tạp cho mã.

Bây giờ với điều đó đã nói, có thể có những công việc bạn đang làm trong VM không liên quan gì đến logic ViewModel của bạn và có thể dễ dàng được phân vùng thành lớp riêng của nó. Điều này sẽ làm giảm kích thước của ViewModel mà không làm tăng độ phức tạp chung của mã.

Tôi đoán đó chỉ là một cách nói rất dài dòng "Nó phụ thuộc và chúng ta không thể nói mà không thấy mã trong câu hỏi".


Cảm ơn câu trả lời của bạn. Tôi chưa bao giờ đọc về việc có nhiều cặp View-VM - nghe có vẻ là một ý tưởng thú vị. Đối với phần còn lại tôi đã thêm nó vào câu hỏi của tôi.
Edgar

Chế độ xem trong cặp nhiều View-VM này là gì(a UserControl/a Grid/a Page ??)
Tên mã Jack

0

Nếu tôi, người không biết gì về ứng dụng của bạn, phải thêm một trường mới qua trường họ hoặc thay đổi thứ tự của một vài trường ... Tôi có thấy dễ dàng hay nản chí không?

Tôi không tin tưởng vào các vùng vì trình biên dịch sẽ không kiểm tra xem bạn có đặt sai thứ gì đó trong vùng không

Bạn phải phát triển phần mềm với mục đích giúp mọi người dễ dàng xây dựng dựa trên những gì bạn tạo ra.


Bạn đã bao giờ tạo một hình thức trong WPF? Nếu có, thì bạn nên biết rằng bạn sẽ làm những gì bạn mô tả trong phần XAML của biểu mẫu chứ không phải trong mã phía sau hoặc VM. Hoặc để trả lời câu hỏi của bạn: Có, nó sẽ rất dễ dàng.
Edgar

@Edgar Lỗi của tôi. Bạn đã nói về các thành phần trực quan và điều khiển người dùng và tôi nghĩ đó là tất cả. Nếu tất cả hình ảnh của bạn nằm trong tầm nhìn và tất cả logic kinh doanh của bạn trong mô hình, bạn không nên lo lắng về việc có một VM dài.
Một chiếc Bravo Dev
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.