2010-03-08 27 views
14

Tôi có kiểu xem với thuộc tính FieldsObservableCollection<FieldVM>. Trong quan điểm cho rằng sử dụng thuộc tính này, tôi có một ItemsControl như vậy:DataTemplate.DataType thay thế trong Silverlight

... 
<ItemsControl ItemsSource="{Binding Fields}" /> 
... 

FieldVM là một lớp trừu tượng, bởi các lớp học như vậy thực hiện như TextFieldVMEnumFieldVM. Trong thời gian chạy, các FieldVM -thực hiện này được thêm vào thuộc tính Fields và tôi muốn chúng hiển thị trong chế độ xem của tôi với chế độ xem được liên kết.

Trong WPF, thực hiện điều này rất đơn giản, tôi luôn làm điều đó. Bạn chỉ cần làm điều này trong một từ điển tài nguyên thích hợp, và mọi thứ hoạt động như mong đợi:

<DataTemplate DataType="{x:Type vm:TextFieldVM}"> 
    <v:TextFieldView /> 
</DataTemplate> 

<DataTemplate DataType="{x:Type vm:EnumFieldVM}"> 
    <v:EnumFieldView /> 
</DataTemplate> 

Bây giờ, làm việc trong Silverlight cho lần đầu tiên, tôi mong đợi Tôi chỉ có thể làm điều tương tự, nhưng DataTemplate không có một tài sản DataType. Tôi bối rối. Silverlight-cách làm điều này là gì?

Trả lời

7

Sử dụng Chuyển đổi giá trị gia tăng để ràng buộc kiểu để tầm nhìn của mỗi điểm:

<DataTemplate> 
    <Grid> 
     <v:EnumFieldView 
      Visibilty="{Binding Converter={StaticResource ViewVisibilityConverter}, ConverterParameter=Enum}" /> 
     <v:TextFieldView 
      Visibilty="{Binding Converter={StaticResource ViewVisibilityConverter}, ConverterParameter=Text}" /> 
    </Grid 
</DataTemplate> 

Và trong ConvertTo của ViewVisibilityConverter, chuyển đổi khả năng hiển thị dựa trên loại.

Một cách khác để xem xét nó là sử dụng một loại công cụ chuyển đổi giá trị khác để trả về một mẫu dữ liệu khác từ Application.Resources.

<ListBox ItemTemplate="{Binding Converter={StaticResource ItemTemplateFactory}"/> 

trong ItemTemplateFactory.Convert():

var fieldVM = value as FieldVM; 

switch fieldVM.FieldType: 
{ 
    case "Text": 
     return Application.Current.Resources["TextTemplate"] as DataTemplate; 

    case "Enum": 
     return Application.Current.Resources["EnumTemplate"] as DataTemplate; 

} 
+3

Cảm ơn đề xuất của bạn. Nó hoạt động, và tôi đánh dấu nó là câu trả lời, nhưng nó không thực sự là một giải pháp lý tưởng ... nó là một hack xấu xí hơn. Tôi không thể không cảm thấy như có một cách thích hợp hơn, giống như WPF để làm điều này. – Alex

+0

Tôi đã thêm một tùy chọn bổ sung có thể đẹp hơn một chút: –

+0

@ Alex: Tôi nhận ra rằng tôi đã trễ một năm để chơi game ở đây, nhưng tôi đã thực hiện một hành vi đính kèm 'BooleanVisibility' mà bạn có thể thấy thú vị. Bạn có thể tìm thấy phần ghi ở đây: http://www.executableintent.com/attached-behaviors-part-1-booleanvisibility/. Phần 2 của loạt bài này có một mẫu mã với một khung hành vi đính kèm và thực thi 'BooleanVisibility'. –

3

Silverlight không có DataTemplateSelector nhưng tôi đã sử dụng đoạn mã này ...

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <client:TemplateSelector Content="{Binding}"/> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 

Dưới đây là các mẫu selector:

public class TemplateSelector : ContentControl 
{ 
    protected override void OnContentChanged(object oldContent, object newContent) 
    { 
     base.OnContentChanged(oldContent, newContent); 

     MyObject f = newContent as MyObject; 

     switch (f.MyProperty) 
     { 
      case "Bool": 
      case "String": 
      case "Array": 
      default: 
       ContentTemplate = Application.Current.Resources["MultiSelectDataTemplate"] as DataTemplate; 
       break; 
     } 
    } 
} 
+0

DataTemplateSelector không có sẵn trong Silverlight ... Nhưng tôi đã thấy một vài cố gắng triển khai lớp này trong Silverlight. Đây là một: http://skysigal.xact-solutions.com/Blog/tabid/427/EntryId/1000/Silverlight-a-port-of-the-DataTemplateSelector.aspx –

+0

DataTemplateSelector không thuộc Silverlight 4 – Jehof

+0

Bạn đúng rồi. Tôi đã sử dụng một đoạn trích khác để thay thế. Chỉnh sửa. – funwhilelost

4

Biến thể trên tùy chọn thứ hai từ Michael (vì tôi không thể làm cho nó hoạt động trực tiếp).

Trong các nguồn lực xác định một datatemplate thêm:

<DataTemplate x:Key="DynamicTemplate"> 
    <ContentPresenter ContentTemplate="{Binding Converter={StaticResource TemplateChooser}}" Content="{Binding}"/> 
</DataTemplate> 

Và sau đó sử dụng mẫu dữ liệu này trong ListBox

<ListBox ItemTemplate="{StaticResource DynamicTemplate}"> 

TemplateChooser phải là một IValueConvertor, nơi mà các chức năng Chuyển đổi lấy một đối tượng và trả về DataTemplate nên được sử dụng cho đối tượng đó.

+0

Không phải là câu trả lời hoàn chỉnh, nhưng là một mẹo hay để kiểm soát các mục. –

8

Microsoft Prism library có thực hiện DataTemplateSelector tùy chỉnh, hãy chú ý classnames trong DataTemplate x: Phím:

    <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <prism:DataTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch" IsTabStop="False"> 
          <prism:DataTemplateSelector.Resources> 
           <DataTemplate x:Key="OpenQuestionViewModel"> 
            <Views:OpenQuestionView DataContext="{Binding}"/> 
           </DataTemplate> 

           <DataTemplate x:Key="MultipleSelectionQuestionViewModel"> 
            <Views:MultipleSelectionView DataContext="{Binding}"/> 
           </DataTemplate> 

           <DataTemplate x:Key="NumericQuestionViewModel"> 
            <Views:NumericQuestionView DataContext="{Binding}"/> 
           </DataTemplate> 
          </prism:DataTemplateSelector.Resources> 
         </prism:DataTemplateSelector> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
-4

Bạn đã cố gắng bỏ qua thuộc tính DataType? và chỉ cần viết một cái gì đó như thế này:

<DataTemplate> 
    <v:TextFieldView /> 
</DataTemplate> 

làm việc cho tôi

+0

Mục đích của thuộc tính 'DataType' là cho phép chọn mẫu động - mẫu được áp dụng cho loại dữ liệu thích hợp được sử dụng và các mẫu khác bị bỏ qua. Trong câu trả lời của bạn, TetxFieldView sẽ được sử dụng mọi lúc. –

5

Silverlight 5 sẽ cuối cùng bao gồm chức năng này. Cho đến lúc đó câu trả lời được đánh dấu là một trong những cách tốt hơn tôi đã nhìn thấy.

+1

... và kể từ khi Silverlight 5 hiện đã được giao, bạn không cần loại giải pháp này nữa. Bạn phải bỏ qua bit {x: Type} và chỉ cần chỉ định tên kiểu. –

0

Bài đăng trên blog này: http://www.c-sharpcorner.com/Blogs/1937/ trình bày những gì trông giống như một công cụ chọn mẫu dữ liệu do-it-yourself tốt đẹp giả mạo làm công cụ chuyển đổi giá trị. Nó có lợi thế là không cần phải cài đặt Prism.

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