Как настроить отображение в ListBox с помощью DataTemplate? - PullRequest
0 голосов
/ 24 мая 2019

Мне нужно отобразить карточки в ListBox в определенном макете:

https://imgur.com/a/0U8eqTc

Я пытался найти способ использовать 2 типа DataTemplate, но понятия не имеюкак это сделать.Я решил сделать шаблон, который содержит шаблон из 6 карточек (например):

https://imgur.com/VrOlYcR

Вот как выглядит мой текущий шаблон:

<ControlTemplate x:Key = "CardTemplate" TargetType = "Button">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="4*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Image Grid.Row="0" Source="{Binding Path=Image}"/>
        <TextBlock Grid.Row="1" Text="{Binding Path=Titre}"/>
    </Grid>
</ControlTemplate>

<DataTemplate x:Key="DataTemplate">
    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>

        <Button Grid.Column="0" Grid.Row="0" Template="{StaticResource CardTemplate}"/>

        <Grid Grid.Column="1" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>
            <Button Grid.Row="0" Template="{StaticResource CardTemplate}"/>
            <Button Grid.Row="1" Template="{StaticResource CardTemplate}"/>
        </Grid>

        <Grid Grid.Column="0" Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>
            <Button Grid.Row="0" Template="{StaticResource CardTemplate}"/>
            <Button Grid.Row="1" Template="{StaticResource CardTemplate}"/>
        </Grid>

        <Button Grid.Column="1" Grid.Row="1" Template="{StaticResource CardTemplate}"/>

    </Grid>
</DataTemplate>

Какой янамеревается отобразить в ListBox:

<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
         Name="ListBox" ItemTemplate="{DynamicResource DataTemplate}" 
         ScrollBar.Scroll="ScrollOnBottom">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

Вот как в основном работает моя треска:

class Cards
{
    public List<Card> cards; // list of 6 Card objects
}

class Card
{
    string title;
    BitmapImage image;

    public string Title { get => title; set => title = value; }
    public BitmapImage Image { get => image; set => image = value; }
}

ObservableCollection<Cards> cc = new ObservableCollection<Cards>();
/*

Cards are already filled with 6 Card
cc filled with Cards

*/
formationListBox.ItemsSource = cc;

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

1 Ответ

1 голос
/ 25 мая 2019

Привести пример того, что прокомментировал Синатр. Вы должны подходить к этому с точки зрения Mvvm. сначала вы должны добавить модель представления для вида, в котором находится это окно. Он будет содержать список объектов, которые DisplayCards, каждый объект будет хранить строку и изображение.

public class DisplayCard : INotifyPropertyChanged
{
    private string _title;
    public string Title
    {
        get { return _title; }
        set
        {
            if (value != _title) { _title = value; RaisePropertyChanged(); }
        }
    }
    private string _cardImage;
    public string CardImage
    {
        get { return _cardImage; }
        set
        {
            if (value != _cardImage) { _cardImage = value; RaisePropertyChanged(); }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
public class YourViewVM : INotifyPropertyChanged
{
    private ObservableCollection<DisplayCard> _cardCollection;
    public ObservableCollection<DisplayCard> CardCollection
    {
        get { return _cardCollection; }
        set
        {
            if (value != _cardCollection) { _cardCollection = value; RaisePropertyChanged(); }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Затем вам нужно сделать список CardCollection установленным в ItemSource ListBox. Затем используйте табличку с данными для привязки свойств DisplayCards к содержащемуся объекту.

<ListBox Name="lbTodoList" HorizontalContentAlignment="Stretch" ItemSource="{Binding CardCollection}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="4*"/>
          <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Image Grid.Row="0" Source="{Binding Image}"/>
        <TextBlock Grid.Row="1" Text="{Binding Title}"/>
      </Grid>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Вы должны убедиться, что вы установили YourViewVM в качестве DataContext представления. Простой поиск должен решить, как это сделать.

Вышеприведенного должно быть достаточно, чтобы вы могли реорганизовать свой код так, чтобы он работал.

...