2016-01-21 32 views
8

Tôi đã làm một chương trình WPF nhỏ một thời gian dài trước đây, nhưng tôi chỉ trở lại xaml với UWP, nhưng tôi nghĩ rằng điều này sẽ làm việc và không thể hiểu tại sao. Về cơ bản tôi muốn sử dụng một ItemsControl (vì tôi chỉ muốn liệt kê một số dữ liệu, tôi không muốn lựa chọn) thay vì một điều khiển ListView. Dưới đây là các nguồn lực của tôi:ItemsControl và ItemTemplateSelector trong Windows 10 Ứng dụng UWP

<Page.Resources> 
    <DataTemplate x:Key="SentMessageDataTemplate"> 
     <TextBlock Text="Sent" /> 
    </DataTemplate> 
    <DataTemplate x:Key="ReceivedMessageDataTemplate"> 
     <TextBlock Text="Recieved" /> 
    </DataTemplate> 
    <services:MessageDataTemplateSelector x:Key="MessageDataTemplateSelector" ReceivedTemplate="{StaticResource ReceivedMessageDataTemplate}" SentTemplate="{StaticResource SentMessageDataTemplate}"></services:MessageDataTemplateSelector> 
</Page.Resources> 

Đây là ItemsControl tôi:

<ItemsControl ItemsSource="{Binding Messages}" ItemTemplateSelector="{StaticResource MessageDataTemplateSelector}" /> 

đây là DataTemplateSelector tôi:

public class MessageDataTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate SentTemplate 
    { 
     get; 
     set; 
    } 

    public DataTemplate ReceivedTemplate 
    { 
     get; 
     set; 
    } 

    protected override DataTemplate SelectTemplateCore(object item) 
    { 
     var message = item as MessageViewModel; 
     if (message == null) 
     { 
      return this.SentTemplate; 
     } 

     return message.Sent ? this.SentTemplate : this.ReceivedTemplate; 
    } 
} 

Thay vì hiển thị một trong hai mẫu của tôi nó chỉ hiển thị tên loại ViewModel của tôi (về cơ bản ToString).

Tuy nhiên nếu tôi chuyển từ ItemsControl sang ListView, nó hoạt động tốt.

Mọi đề xuất?

+0

Đã xảy ra sự cố tương tự ở một trong các ứng dụng của tôi gần đây! Tự hỏi nếu điều này có thể giải quyết được không ... – Depechie

Trả lời

9

Sử dụng ghi đè này thay vì:

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) 

Đây là một trong đó được gọi là, không phải là một mà không có tham số thứ 2.

+0

Tôi đã thử điều đó, không may mắn.Các ItemsPanelTemplate là giống như mẫu mặc định. Điều này làm việc tốt nếu tôi thiết lập một ItemTemplate, nó chỉ không giống như ItemTemplateSelectors. – Cleverguy25

+0

Tôi đã cập nhật câu trả lời của mình. Ghi đè với 1 param không bao giờ được gọi (như bạn quan sát). Có sẵn 2. Khôn lanh. –

0

Có thể bạn nên sử dụng <TextBlock Text="{Binding Sent}" /> Bạn không ràng buộc bất kỳ thứ gì trong Mẫu của mình.

+0

Ngay cả khi tôi liên kết thứ gì đó, nó cũng không hoạt động. ListView hoạt động ngay cả khi không ràng buộc bất cứ điều gì. Nếu tôi đặt một breakpoint trong DataTemplateSelector của tôi, nó sẽ không bao giờ được gọi khi chạy trong một ItemsControl. Tôi nghĩ đây chỉ là một lỗi. – Cleverguy25

5

Thú vị - ListView và GridView đều gọi trình chọn mẫu; đồng bằng ItemsControl hoặc ListBox thì không.

Trọng sự phương pháp SelectTemplateCore khác trong mẫu chọn giúp, ví dụ .:

protected override DataTemplate SelectTemplateCore(object item) 
{ 
    var message = item as MessageViewModel; 
    if (message == null) 
    { 
     return SentTemplate; 
    } 

    return message.Sent ? SentTemplate : ReceivedTemplate; 
} 

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) 
{ 
    return SelectTemplateCore(item); 
} 

Phương pháp thứ hai được gọi là trong mọi trường hợp; đầu tiên không được gọi cho ItemsControl mục. This page cung cấp một giải thích về các loại:

Nếu bạn ItemsControl.ItemsPanel là một ItemsStackPanel hoặc ItemsWrapGrid, cung cấp một ghi đè cho phương pháp SelectTemplateCore(Object). Nếu ItemsPanel là một bảng điều khiển khác, chẳng hạn như VirtualizingStackPanel hoặc WrapGrid, hãy ghi đè phương thức SelectTemplateCore(Object, DependencyObject).

+0

Kory đánh bại bạn đến một vài phút, nhưng liên kết của bạn đến tài liệu là hữu ích. – Cleverguy25

0

Dưới đây là những gì các tài liệu nói:

Bình luận

Nếu ItemsControl.ItemsPanel của bạn là một ItemsStackPanel hoặc ItemsWrapGrid, cung cấp một ghi đè cho phương pháp SelectTemplateCore (Object). Nếu ItemsPanel là một bảng điều khiển khác, chẳng hạn như VirtualizingStackPanel hoặc WrapGrid, cung cấp ghi đè cho phương thức SelectTemplateCore (Object, DependencyObject).

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