Я думаю название уже звучит глупо, но давайте разберемся. Суть такова, что мне в столбец DataGrid'а нужно передать коллекцию коллекций, но не просто коллекцию, а вывести все ее элементы. Сейчас объясню. Есть класс Word и класс MeaningGroup
public class Word
{
public String Name { get; set; }
public List<MeaningGroup> MeaningGroups { get; set; }
}
public class MeaningGroup
{
public List<string> Synonyms { get; set; }
public List<string> Acronyms { get; set; }
}
И вот такая разметка в xaml
<Grid>
<DataGrid ItemsSource="{Binding Words}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTemplateColumn x:Name="ListColumn" Header="Synonym and acronyms">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Synonyms}"/>
<TextBlock Text="{Binding Path=Acronyms}"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
и в качестве ItemsSource передаем следующую коллекцию:
Word word1 = new Word() { Name = "word1",MeaningGroups = new List<MeaningGroup>() {group1, group2}};
Word word2 = new Word() { Name = "word2", MeaningGroups = new List<MeaningGroup>() { group1, group2 } };
Word word3 = new Word() { Name = "word3", MeaningGroups = new List<MeaningGroup>() { group1, group2} };
Word word4 = new Word() { Name = "word4", MeaningGroups = new List<MeaningGroup>() { group1, group2 } };
Words = new List<Word> {word1, word2, word3, word4};
В первый столбец мы передаем название, что сделать нетрудно забиндив Name, но вот что делать со столбцом, в который мы передаем List? Надо сделать так, чтобы в данный столбец ("ListColumn"
) мы передавали список MeaningGroup, в котором чтобы group1 и group2 были на разных строках, что я и сделал, добавив два текстблока. Нужно чтобы в первый текстблок передавались все элементы из коллекции group1, а во второй текстблок передавались все элементы из коллекции group2. Если я плохо объяснил, то попробую составить краткий план:
DataGrid
коллекцию List<Word> Words
ListColumn
передавать List<MeaningGroup>
, состоящий из group1
и group2
TextBlock
передать все элементы из коллекции group1
, во второй TextBlock
передать все элементы из коллекции group2
.Я, может, и сам разберусь, но мне нужна помощь в том, как вообще в текстблок передать коллекцию элементов , чтобы он вывел у себя каждый элемент (еще и желательно бы с пробелом) т.е например если мы передаем ему коллекцию List<string> group1
с элементами {"Курица", "Баклажан", "Сосиска"} чтобы его текст был "Курица баклажан сосика"?
По сути тут два варианта:
Отображать коллекцию так, как положено. Для этого в WPF существуют элементы ItemsControl
, которые легко настраиваются так, как вам нужно. Я не буду особо вдаваться в подробности что да как, просто покажу как это использовать на вашем примере:
<DataGridTemplateColumn x:Name="ListColumn" Header="Synonym and acronyms">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ItemsControl ItemsSource="{Binding MeaningGroups}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<ItemsControl ItemsSource="{Binding Synonyms}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="3,3,3,3" Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Acronyms}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="3,3,3,3" Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
То есть мы в ячейке сделали ItemsControl
, который привязали к MeaningGroups
и дальше под каждую коллекцию создали еще по одному ItemsControl
со своим шаблоном (отступ), а также с расположением элементов в ряд (с помощью WrapPanel
, либо любой другой). Как видите код повторяется и не очень удобен, поэтому все нужное стоит вынести в отдельный стиль и его уже использовать.
Преобразовывать коллекцию в string
. Тут вариантов уйма, решайте сами что и как вам будет удобней. Можно создать конвертер; можно создать отдельно свойство, где в get
будет выдаваться нужный текст; а можно и вовсе переопределить .ToString
и там уже вывести что нужно. Я покажу вариант с доп. свойствами:
Свойства:
public string SynonymsString => Synonyms != null ? string.Join(" ", Synonyms) : null;
public string AcronymsString => Acronyms != null ? string.Join(" ", Acronyms) : null;
XAML:
<DataGridTemplateColumn x:Name="ListColumn" Header="Synonym and acronyms">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ItemsControl ItemsSource="{Binding MeaningGroups}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding SynonymsString}"/>
<TextBlock Text="{Binding AcronymsString}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
В общем вариантов решения этой задачи уйма, выбирайте свой. Удачи!
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
В программе несколько форм и каждой так или иначе нужна БД (через класс посредник) для наполнения или записи полученных данных
Столкнулся со странной ошибкойЕсть кнопка button, и событие Click для неё