2009-04-20 34 views
6

Cập nhậtWPF MVVM: Công ước về cấu hình cho ResourceDictionary?

Với tinh thần wiki của StackOverflow, đây là một bản cập nhật:

tôi tăng vọt IValueConverter đề nghị Joe White bên dưới. Nó hoạt động như một say mê.

Tôi đã viết một ví dụ "khởi động nhanh" về việc này tự động hóa ánh xạ của ViewModels-> Views bằng cách sử dụng một số thay thế chuỗi giá rẻ. Nếu không có View nào được tìm thấy để đại diện cho ViewModel, nó sẽ mặc định là một trang "Under Construction". Tôi đang lồng tiếng cho cách tiếp cận này "WPF MVVM White" vì đó là ý tưởng của Joe White. Dưới đây là một vài ảnh chụp màn hình.

Hình ảnh đầu tiên là trường hợp của "[SomeControlName] Chế độ xemMô hình" có chế độ xem "[SomeControlName] tương ứng", dựa trên quy ước đặt tên thuần túy. Thứ hai là trường hợp mà ModelView không có bất kỳ khung nhìn nào để biểu diễn nó. Không còn nhiều ResourceDictionaries với ViewModel dài để xem ánh xạ. Đó là quy ước đặt tên thuần túy ngay bây giờ.

Wpf Mvvm White

tôi đăng một tải của dự án ở đây: Mvvm.White.Quickstart.zip


Original Post

tôi đọc Josh Smith fantastic MSDN article trên WPF MVVM cuối tuần qua. Nó được mệnh danh là một giáo phái cổ điển.

Tôi mất một lúc để quấn đầu quanh sự kỳ diệu khi yêu cầu WPF hiển thị ViewModel.

Giống như nói "Đây là lớp học, WPF. Hãy tìm hiểu xem UI nào sẽ sử dụng để trình bày nó."

Đối với những người bỏ lỡ kỳ diệu này, WPF có thể làm điều này bằng cách tìm Xem cho ModelView trong việc lập bản đồ ResourceDictionary và kéo ra Xem tương ứng. (Cuộn xuống Figure 10 Supplying a View).

Điều đầu tiên mà nhảy ra lúc tôi ngay lập tức là có đã là một quy ước đặt tên vững vàng về:

classNameView ("View" suffix) 
classNameViewModel ("ViewModel" suffix) 

Câu hỏi của tôi là:

Kể từ khi ResourceDictionary thể được thao tác programatically, I "m tự hỏi nếu bất cứ ai đã quản lý để Regex.Đặt lại toàn bộ điều đi, để tra cứu là tự động và bất kỳ Chế độ xem/Chế độ xem mới nào được giải quyết theo quy ước đặt tên của chúng?

[Chỉnh sửa] Những gì tôi đang tưởng tượng là một móc/đánh chặn vào ResourceDictionary.

...Cũng đang xem xét một phương pháp lúc khởi động có sử dụng interop để kéo ra *View$*ViewModel$ tên lớp để xây dựng từ điển DataTemplate trong mã:

//build list 
foreach .... 
    String.Format("<DataTemplate DataType=\"{x:Type vm:{0} }\"><v:{1} /></DataTemplate>", ...) 
+0

Oh yeah đó bài viết rất hay. Tôi sử dụng RelayCommand của mình trong mọi dự án, ngoại trừ việc tôi đã thêm thuộc tính Tên và Mô tả cho liên kết một lần các nội dung như văn bản nút và chú giải công cụ. – Botz3000

+0

Có một khuôn khổ MVVM ngoài kia (tôi đã xem rất nhiều mà tôi quên cái này được gọi là) mà chính xác những gì bạn đang nói về. Khi tôi nhớ lại được sử dụng quy ước tên để tự động xem các lượt xem đến các mô hình chế độ xem của họ. Tôi ghét nó. Nó trông giống như ma thuật đen. Khi bạn đang xem mã, bạn không bao giờ có thể nói rõ cách các mảnh được nối với nhau. Tôi muốn xác định các mẫu dữ liệu chế độ xem của mình trong ngữ cảnh đôi khi để mô hình xem/xem được liên kết rất rõ ràng. –

+1

[Liên kết dự án] (http://rootsilver.com/files/Mvvm.White.Quickstart.zip) bị lỗi. Bạn có thể tải lại lên địa điểm khác không? –

Trả lời

17

Thay vì viết mã để thêm một cách rõ ràng điều cần các ResourceDictionary, làm thế nào về chỉ tạo quyền xem theo yêu cầu? Bạn có thể làm điều này với một ValueConverter.

nguồn lực của bạn sẽ trông như thế này:

<Views:ConventionOverConfigurationConverter x:Key="MyConverter"/> 
<DataTemplate DataType="{x:Type ViewModels:ViewModelBase}"> 
    <ContentControl Content="{Binding Converter={StaticResource MyConverter}}"/> 
</DataTemplate> 

Bạn vẫn cần một nguồn lực DataTemplate, nhưng miễn là ViewModels của bạn tất cả đều có một lớp cơ sở chung, bạn sẽ chỉ cần một DataTemplate để chăm sóc tất cả của họ.

Sau đó xác định các lớp chuyển đổi giá trị:

public class ConventionOverConfigurationConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
     CultureInfo culture) 
    { 
     // value is the ViewModel. Based on its GetType(), build a string 
     // with the namespace-qualified name of the view class, then: 
     return Activator.CreateInstance(Type.GetType(viewName)); 
    } 
    public object ConvertBack(object value, Type targetType, 
     object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

Tất cả các bạn cần phải làm là viết logic bên trong Chuyển đổi, mà sẽ phụ thuộc vào những thứ như xem xem và ViewModels của bạn trong không gian tên tương tự hay không .

+0

rằng, thưa bạn, chính xác là những gì tôi muốn làm! =) –

+0

Cảm ơn Joe - Tôi đã cập nhật câu hỏi này dựa trên phản hồi của bạn. –

+0

Tuyệt vời! Đó là cắt của tôi App.xaml từ một vài trăm dòng đến một vài chục :) – Grokys

-1

tôi quyết định làm được khá nhiều điều hthe cùng vì vậy tôi tải DataTemplates tôi trực tiếp vào ResourceDictionary sử dụng

private void RegisterResources() 
    { 
     ResourceDictionary dictionary = new ResourceDictionary(); 
     dictionary.Source = new Uri("pack://application:,,,/StartupModule;Component/UIResources.xaml"); 
     Application.Current.Resources.MergedDictionaries.Add(dictionary); 
    } 

nơi tệp UIResources là một tập tin xamls ResourceDictionary chứa tất cả DataTemplates của chúng tôi

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