В этом посте я объясню, как я выбирал разные шаблоны в зависимости от типа данных, которые я хотел показать в одном и том же списке.
Теперь, почему вы хотите, чтобы 2 разных шаблона в одном списке? Что ж, если вы хотите отображать различные задачи и встречи в течение одного дня. Но вы хотите быстро увидеть, что такое задание и что такое назначение. Допустим, у вас есть квадрат для всех задач и круг для всех встреч.
Для этого вы будете использовать ContentControl, который при привязке данных к списку будет переопределять метод, чтобы проверить, является ли привязываемый элемент задачей или назначением. А затем установить шаблон в зависимости от того, что это такое.
В моем примере кода задачи и назначения наследуются от класса CalendarItem. Это принцип объектно-ориентированного программирования, и если вы его не понимаете, дайте мне знать, и я создам блог об его основах.
Сначала я подумал о том, чтобы создать шаблоны, которые я буду использовать для задач и встреч. Я создал отдельный файл с именем «DataTemplates.xaml» и поместил его в папку «Ресурсы».
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <DataTemplate x:Key="TaskTemplate"> <StackPanel Orientation="Horizontal" Margin="0, 6"> <Grid Margin="12, 0, 12, 0"> <Rectangle Fill="{Binding categoryColor}" Width="20" Height="20"/> </Grid> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding title}" HorizontalAlignment="Left" TextWrapping="Wrap" FontSize="24" Width="300"/> <TextBlock Text="{Binding time}" HorizontalAlignment="Right" FontSize="24" Width="112"/> </StackPanel> </StackPanel> </DataTemplate> <DataTemplate x:Key="ApptTemplate"> <StackPanel Orientation="Horizontal" Margin="0, 6"> <Grid Margin="12, 0, 12, 0"> <Ellipse Fill="{Binding categoryColor}" Width="20" Height="20"/> </Grid> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding title}" HorizontalAlignment="Left" TextWrapping="Wrap" FontSize="24" Width="300"/> <TextBlock Text="{Binding time}" HorizontalAlignment="Right" FontSize="24" Width="300"/> </StackPanel> </StackPanel> </DataTemplate> </ResourceDictionary>
Когда вы посмотрите на этот код, вы увидите, что структуры шаблонов выглядят одинаково, но одна использует прямоугольник, а другая использует эллипс. Теперь в классе CalendarItem все имеет категорию и категорию, цвет, заголовок и время. Таким образом, мы использовали все эти данные для отображения.
Следующим шагом будет создание переопределения с помощью ContentControl. Создайте файл класса в своем решении, я назвал мой «TemplateSelector.cs».
using System.Windows.Controls; using System.Windows; using System.Windows.Markup; using System.Xml.Linq; namespace DuelTemplateSample.Helpers { public class DataTemplateHelper { public static DataTemplate LoadFromDictionary(string dictionary, string template) { var doc = XDocument.Load(dictionary); var dict = (ResourceDictionary)XamlReader.Load(doc.ToString(SaveOptions.None)); return dict[template] as DataTemplate; } } public class templateSelector : ContentControl { protected override void OnContentChanged(object oldContent, object newContent) { base.OnContentChanged(oldContent, newContent); var calItem = (CalendarItem)newContent; if (calItem.type == "APPT") { ContentTemplate = DataTemplateHelper.LoadFromDictionary( "DuelTemplateSample;component/Resources/DataTemplates.xaml", "ApptTemplate"); } else { ContentTemplate = DataTemplateHelper.LoadFromDictionary( "DuelTemplateSample;component/Resources/DataTemplates.xaml", "TaskTemplate"); } } } }
Как видно из кода ContentControl, мы переопределяем метод OnContentChanged, который принимает 2 объекта. oldContent и newContent. Если вы не понимаете, что такое переопределение, это еще один принцип объектно-ориентированного программирования. Затем мы вводим тип (то есть устанавливаем объект как другой тип), в этом случае мы говорим, что newContent является CalendarItem. Затем мы проверяем тип: это свойство элемента календаря, это будет либо «APPT» для встречи, либо «TASK» для задачи. Затем, в зависимости от типа, мы загружаем ContentTemplate из файла DateTemplate и имя шаблона. В коде я вызываю метод с именем LoadFromDictionary, который определен в коде выше OnContentChanged. Все, что он делает — загружает файл xaml, который вы создали ранее, и получает шаблон, соответствующий имени шаблона.Как вы можете видеть, я отправляю строку, в которой указано местоположение файла xaml, этот формат используется для указания местоположения файла в приложении «DuelTemplateSample;» сообщает, в каком пространстве имен находится файл, а «component / Resources / DataTemplates.xaml» сообщает, что файл находится в папке Resources. Компонент означает, что он находится в «корне» проекта.
Сейчас самое время настроить работу в ListBox. На вашей странице xaml, которая будет содержать ListBox, добавьте
xmlns:templateSelector="clr-namespace:DuelTemplateSample.Helpers"
в PhoneApplicationPage со всеми другими пространствами имен. Как видите, «DuelTemplateSample.Helpers» — это пространство имен, в котором находится templateSelector / OnContentChanged. Теперь для ListBox мой выглядит так
<ListBox x:Name="DuelListBox" SelectionChanged="DuelListBox_SelectionChanged" Height="133" Margin="0,475,0,0" VerticalAlignment="Top" > <ListBox.ItemTemplate> <DataTemplate> <templateSelector:templateSelector Content="{Binding}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Как видите, я установил DataTemplate на
<templateSelector:templateSelector Content="{Binding}"/>
Это то, что вызывает метод переопределения OnContentChange и устанавливает шаблон в соответствии с типом, который мы кодировали ранее.
Теперь все, что вам нужно сделать, это привязать набор данных к ListBox и проверить результаты. В этом случае у меня есть список CalendarItems с набором задач и встреч и загружаю его в ListBox в коде позади.
Я надеюсь, что это поможет, и если вы не уверены, есть какие-либо вопросы или комментарии, пожалуйста, напишите или напишите мне на andy (at) underbridgecity.net.