2010-07-04 26 views
6

Silverlight 4 đã hết và có vẻ như chúng tôi đã bỏ lỡ chức năng DataType DataType trong bản phát hành này một lần nữa, điều này khá quan trọng đối với hỗ trợ MVVM IMHO. Đối với các ứng dụng WPF của tôi, tại thời điểm này, tôi khá quen với việc thêm DataTemplates trên toàn cầu cho Chế độ xem vào Ứng dụng của tôi. Tài nguyên với DataTypes cho ViewModels tương ứng của tôi:Silverlight 4 DataTemplate DataType

tức là.

<DataTemplate DataType="{x:Type viewModels:myViewModel}"> 
<views:myView/> 
</DataTemplate> 

Tôi thích cách tiếp cận này, vì tất cả ViewModels ràng buộc của tôi tự động hiển thị các nội dung chính xác ... đặc biệt hữu ích khi tôi có một số ItemSource trong quan điểm của tôi bị ràng buộc vào một tập hợp các ViewModels ... Đây, ví dụ, sẽ tự động đảm bảo mỗi tab trong TabControl được liên kết với một số Collection<SomeViewModel> hiển thị chế độ xem được liên kết với SomeViewModel.

Một số điều tôi đã cố gắng cho SL 3 bao gồm:

  • Tạo một "DataTemplatePresenterContentControl" mà tự động áp dụng một DataTemplate cho nội dung khi kiểm soát đã nạp

  • Sử dụng một TypeConverter, áp dụng tự động trên kiểm soát tải, đi bộ xuống cây thị giác tìm kiếm các đối tượng dữ liệu bị ràng buộc

  • Sử dụng kiểu, được áp dụng động trên tải kiểm soát, đi xuống dưới chế độ xem hình ảnh của cây g đối với các đối tượng dữ liệu bị ràng buộc

Tuy nhiên, không cách nào trong số này thực sự giải quyết tình huống tôi đã đề cập ở trên, điều này thực sự quan trọng.

Vì vậy, vì điều này vẫn không thể thoát khỏi hộp trong Silverlight 4, tôi rất muốn biết liệu có ai chưa đưa ra một số giải pháp thay thế hợp lý hay không.

Cảm ơn.

Trả lời

8

Con đường tôi làm điều đó trong một vài dự án thương mại như sau:

Tôi có một IValueConverter chuẩn

public class ViewTemplateChooser : IValueConverter 
{ 
    /// <summary> 
    /// Modifies the source data before passing it to the target for display in the UI. 
    /// </summary> 
    /// <returns> 
    /// The value to be passed to the target dependency property. 
    /// </returns> 
    /// <param name="value">The source data being passed to the target.</param><param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param><param name="parameter">An optional parameter to be used in the converter logic.</param><param name="culture">The culture of the conversion.</param> 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is MyViewModel) 
     { 
      return new MyView { DataContext = value }; 
     } 

     return value; 
    } 

    /// <summary> 
    /// Modifies the target data before passing it to the source object. This method is called only in <see cref="F:System.Windows.Data.BindingMode.TwoWay"/> bindings. 
    /// </summary> 
    /// <returns> 
    /// The value to be passed to the source object. 
    /// </returns> 
    /// <param name="value">The target data being passed to the source.</param><param name="targetType">The <see cref="T:System.Type"/> of data expected by the source object.</param><param name="parameter">An optional parameter to be used in the converter logic.</param><param name="culture">The culture of the conversion.</param> 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Bộ chuyển đổi sẽ yêu cầu đăng ký tên miền không gian

xmlns:Converters="clr-namespace:YourProject.Converters" 

Sau đó, bạn tham chiếu trình chuyển đổi trong phần tài nguyên của mình:

<UserControl.Resources> 
    <Converters:ViewTemplateChooser x:Key="TemplateChooser" /> 
</UserControl.Resources> 

và cuối cùng tôi sử dụng công cụ chuyển đổi để chuyển đổi các ViewModel trong Chế độ xem với DataContext của quan điểm thiết lập để ViewModel

<ContentControl Content="{Binding Workspace, Converter={StaticResource TemplateChooser}}" Margin="5,35,5,5" Grid.Column="1" /> 

Bộ chuyển đổi có thể được sửa đổi để thực hiện chiến lược Navigation, tôi đã cố gắng để làm ví dụ càng đơn giản càng tốt.

Tôi hy vọng điều này sẽ giúp bạn không phải đi đến thái cực - hoặc thư viện của bên thứ ba - để có được những gì bạn đang tìm kiếm.

1

Trong WPF và Silverlight, tôi sử dụng Prism để làm điều này. Tôi thấy nó linh hoạt hơn nhiều để chuyển chế độ xem dựa trên các loại. Nó đòi hỏi một chút để có được nó strapped in, nhưng một khi nó được, khả năng là vô tận.

Sửa

Tôi làm điều này bằng cách liên kết các RegionName để sở hữu một trong ViewModel của tôi (Có thể là GetType(). Đặt tên nếu bạn muốn). Sau đó, tôi đăng ký các loại cho tên, và nó chỉ hoạt động.

Trong trường hợp của một cái gì đó giống như một ListBox, tôi thiết lập các mẫu dữ liệu được:

<ContentControl Regions:RegionManager.RegionName="{Binding SomeName}" /> 

Nếu bạn không muốn SomeName để được vào đối tượng bạn đang gắn vào, hãy xem xét một ValueConverter rằng trả về tên loại:

<ContentControl Regions:RegionManager.RegionName="{Binding SomeName, Converter={StaticResource ObjectToTypeConverter}}" /> 

Điều đó có hữu ích không?

+0

Tôi cũng đang sử dụng RegionManager của Prism, nhưng bạn có thể giải thích thêm một chút về chi tiết cụ thể về cách bạn đang thực hiện việc này không? – Jeff

+0

Sự tham gia trong bản chỉnh sửa của tôi ở trên. –

+0

Vâng, cảm ơn. Tôi thích cách tiếp cận này. Nhưng nó vẫn không giải quyết được một vấn đề tôi đã đề cập ở trên; ràng buộc với một IEnumerable - ví dụ ràng buộc một TabControl đến một Bộ sưu tập và mong đợi mỗi tab để hiển thị MyViewForMyViewModelClass UserControl. Hoặc có cách nào để thích ứng với cách tiếp cận của bạn để hỗ trợ điều đó không? Cảm ơn. – Jeff

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