2012-04-04 27 views
13

Tôi có một ViewModel được định nghĩa như thế này:Làm cách nào để tham chiếu một loại chung trong thuộc tính DataType của DataTemplate?

public class LocationTreeViewModel<TTree> : 
       ObservableCollection<TTree>, INotifyPropertyChanged 
                where TTree : TreeBase<TTree> 

Tôi muốn tham khảo nó trong các thuộc tính DataType của một DataTemplate trong XAML. Làm thế nào tôi có thể làm điều đó?

+0

thể trùng lặp của [Tôi có thể chỉ định một loại generic trong XAML?] (Http://stackoverflow.com/questions/185349/can-i-specify-a-generic-type-in-xaml) – franssu

Trả lời

-2

Cách duy nhất tôi có thể thực hiện việc này là sử dụng MarkupExtensions.

public class GenericType : MarkupExtension 
{ 
    private readonly Type _of; 
    public GenericType(Type of) 
    { 
     _of = of; 
    } 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return typeof(LocationTreeViewModel<>).MakeGenericType(_of); 
    } 
} 

Và để sử dụng nó tôi chỉ cần làm điều này:

<DataTemplate DataType="{app:GenericType app:TreeBaseClass}"> 
+1

Đó là một giải pháp kém vì nó được kết hợp với lớp LocationTreeViewModel .. – franssu

+0

@franssu: Cảm ơn bạn đã bình luận, nhưng tôi không hiểu ý bạn là gì? Tôi không muốn sử dụng nó cho mọi lớp học chung, tôi không không nghĩ rằng nó thậm chí có thể! Bạn có giải pháp tốt hơn không? –

+1

-1: Thật không may điều này gây ra lỗi MC; 'DataType' của' DataTemplate' chỉ có thể chấp nhận một tập hợp các phần mở rộng được xác định trước [như 'x: Type']. Suck up [@ ColinE của câu trả lời] (http://stackoverflow.com/a/10005490/11635) là kết luận của tôi –

8

Không, bạn không thể biểu thị loại generics trong XAML. Bạn sẽ phải tạo một loại cụ thể mở rộng loại chung của bạn ...

public class FooLocationTreeViewModel : LocationTreeViewModel<Foo> 
{ 
} 
+0

Tôi đã sử dụng kỹ thuật này với thành công nhưng cuối cùng [xây dựng một trình bao bọc chung, xem câu trả lời của tôi giải thích về điều này] (http://stackoverflow.com/a/33827448/11635) –

3

Trong XAML 2006, điều này không được hỗ trợ. Bạn có thể, tuy nhiên, cuộn của riêng bạn nếu bạn muốn có chức năng này.

This link có hướng dẫn tốt về cách tạo tiện ích mở rộng đánh dấu.

Cách sử dụng sẽ là như thế này:

<Grid xmlns:ext="clr-namespace:CustomMarkupExtensions"> 
    <TextBlock Text="{ext:GenericType FooLocationTreeViewModel(Of Foo)}" /> 
</Grid> 

Bạn phải chọn và thực hiện các cú pháp mặc dù. Tôi đề nghị ký hiệu VB vì nó sẽ không can thiệp như ký hiệu C# với < và>.

+2

sẽ không hoạt động như bit 'DataType' của' DataTemplate' không cho phép phần mở rộng đánh dấu –

-1

phiên bản cải tiến của Hơi MarkupExtension, làm việc cho các lớp học tối đa 3 thông số chung chung.

public class GenericTypeExtension : MarkupExtension 
    { 
    public GenericTypeExtension() 
    { 

    } 
    public GenericTypeExtension(string baseTypeName_, Type genericType1_, Type genericType2_, Type genericType3_) 
    { 
     BaseTypeName = baseTypeName_; 
     GenericType1 = genericType1_; 
     GenericType2 = genericType2_; 
     GenericType3 = genericType3_; 
    } 
    public string BaseTypeName { get; set; } 
    public string BaseTypeAssemblyName { get; set; } 
    public Type GenericType1 { get; set; } 
    public Type GenericType2 { get; set; } 
    public Type GenericType3 { get; set; } 

    public override object ProvideValue(IServiceProvider serviceProvider_) 
    { 
     var list = new List<Type>(); 
     if (GenericType1 != null) 
     { 
     list.Add(GenericType1); 
     } 
     if (GenericType2 != null) 
     { 
     list.Add(GenericType2); 
     } 
     if (GenericType3 != null) 
     { 
     list.Add(GenericType3); 
     } 

     var type = Type.GetType(string.Format("{0}`{1}, {2}", BaseTypeName, list.Count, BaseTypeAssemblyName)); 
     if (type != null) 
     { 
     return type.MakeGenericType(list.ToArray()); 
     } 
     return null; 
    } 

    } 
+0

Điều này không trả lời OP - không sử dụng cho datatemplates –

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