Создать DataGridRows для наблюдаемой коллекции пользовательских классов с помощью изображений и текста

Я искал решение своей проблемы все выше и ниже, но не смог найти ничего подходящего. На данный момент я в полной растерянности.

У меня есть собственный класс, который имеет свойство BitmapImage и свойство String. Давайте назовем этот класс "BusinessCard". У меня тоже есть:

ObservableCollection CompanyCards = new ObservableCollection();

Каждый массив BusinessCard[] содержит изображение визитной карточки каждого сотрудника, а также их имя (вышеупомянутые свойства BitmapImage и String)

Я хочу, чтобы каждая строка представляла каждую компанию, а каждая колонка представляла визитную карточку.

Пример: у меня есть компания A, компания B и компания C. Допустим, у меня есть три карты для A, четыре для B и две для C. Я хочу, чтобы мой вывод выглядел следующим образом (исключая часть "Row #"):

Row [Card] | [Card] | [Card]
 1   Name  |  Name  |  Name
----------------------------------
Row [Card] | [Card] | [Card] | [Card]
 2   Name  |  Name  |  Name  |  Name
----------------------------------
Row [Card] | [Card]
 3   Name  |  Name

BusinessCard класс

public class BusinessCard: INotifyPropertyChanged
{
    private BitmapImage _image;
    private string _personName;
public BusinessCard() { }
public BusinessCard(BitmapImage image, string personName)
    {
        this.CardImage = image;
        this.Name = personName;
    }
public BitmapImage CardImage 
    {
    get { return _image; }
    set
        {
            _image = value;
            NotifyPropertyChanged();
        }
    }
public string Name
    {
    get { return _personName; }
    set
        {
            _personName = value;
        }
    }

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Что я пробовал

XAML

Это работало, но, конечно, работало только для одной BusinessCard из каждой компании, отображаемой в каждой строке (правильное количество строк, но не столбцов):

    <DataGrid x:Name="CardViewer" AutoGenerateColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False" CanUserAddRows="False" Grid.Column="0" ItemsSource="{Binding CompanyCards}">
        <DataGrid.Columns>
                <DataGridTemplateColumn Header="Cards" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                                <Image Source="{Binding CardImage}"/>
                                <Label Content="{Binding Name}"/>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

Я также пробовал это, но это создало строки, но в них явно не было контента, так как они были высотой ~10 пикселей, и я не мог изменить их размер, даже если для параметров UserResize было задано значение true:

XAML

<DataGrid x:Name="CardViewer" AutoGenerateColumns="False" CanUserResizeColumns="True" CanUserResizeRows="True" CanUserSortColumns="False" CanUserAddRows="False" Grid.Column="0"/>

Код позади

    public ObservableCollection<DataGridRow> spList = new ObservableCollection<DataGridRow>();

    foreach(BusinessCard[] bca in CompanyCards)
        {
            StackPanel sp = new StackPanel();
            sp.Orientation = Orientation.Horizontal;
            sp.MinHeight = 32;
            DataGridRow dgr = new DataGridRow();
        foreach(BusinessCard bcb in bca)
            {
                Image img = new Image();
                img.Stretch = Stretch.Uniform;
                img.Source = bcb.CardImage;

                Label lbl = new Label();
                lbl.Content = rcb.Name;

                sp.Children.Add(img);
                sp.Children.Add(lbl);
            }
            dgr.Item = sp;
            spList.Add(dgr);
        }

        CardViewer.DataContext = spList;
        CardViewer.ItemsSource = spList;

Я думаю, что попробовал другие варианты двух, но у всех был тот же самый результат. Пожалуйста помоги? Я чувствую, что что-то очень простое, что мне не хватает...

1 ответ

Решение

Поскольку каждый столбец в вашей сетке представляет массив, вы должны изменить шаблон ячейки, чтобы использовать ItemsControl:

   <DataGrid x:Name="CardViewer" AutoGenerateColumns="False" CanUserResizeColumns="False" 
          CanUserResizeRows="False" CanUserSortColumns="False" CanUserAddRows="False" Grid.Column="0" 
          ItemsSource="{Binding}">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Cards" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{Binding}" >
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                   <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                        <Image Source="{Binding CardImage}" Height="50" Width="50"/>
                        <Label Content="{Binding Name}"/>
                    </StackPanel> 
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel Orientation="Horizontal"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                    </ItemsControl>

                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>
Другие вопросы по тегам