0

I'm trying to display some albums in controls with size determined in runtime

XAML:

    <Grid>
    <Grid.Resources>
        <DataTemplate x:Key="AlbumsTemplate">
            <Grid>
                <Border Width="{Binding ThumbWidth}" Height="{Binding ThumbHeight}">
                    <Border.Background>
                        <ImageBrush ImageSource="{Binding Cover}"/>
                    </Border.Background>
                </Border>
                <StackPanel>
                    <TextBlock Text="{Binding Artist}" />
                    <TextBlock Text="{Binding Name}" />
                </StackPanel>
            </Grid>
        </DataTemplate>
    </Grid.Resources>

    <Grid.RowDefinitions>
        <RowDefinition />
    </Grid.RowDefinitions>

    <ListBox ItemsSource="{Binding Albums}" ItemTemplate="{DynamicResource AlbumsTemplate}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
</Grid>

Code behind

 public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }

ViewModel.cs

    class ViewModel
{
    private ObservableCollection<Album> Albums { get; set; }
    public int ThumbWidth { get; set; }
    public int ThumbHeight { get; set; }

    public ViewModel()
    {
        ThumbWidth = 150;
        ThumbHeight = 150;
        Albums = DataSupplier.Instance.GetAlbums();
    }
}

Album Class

    class Album
{
    public string Name { get; set; }
    public string Artist { get; set; }
    public BitmapImage Cover { get; set; }

    public Album(string name, string artist, BitmapImage cover)
    {
        Name = name;
        Artist = artist;
        Cover = cover;
    }
}

I can see all albums with name, artist, and cover, but the cover has no the correct size.

In controls outside the DataTemplate I can retrieve ThumbWidth and ThumbHeight

What am I missing?

fernavat
  • 3
  • 1

2 Answers2

1

The Problem is that your current DataContext is Album and not ViewModel. You can only have one DataContext.

  1. A fast way to solve this problem would be to add ThumbWidth and ThumbHeight to your Album-class.

  2. I would prefer to add a class AlbumViewModel which contains all kind of information, which is need for showing the album (like: witdh, height, name, title, ...). In addition a list of AlbumViewModels is located in your ViewModel. Doing it like this is common used solution for your problem in MVVM.

  3. Another hacky way is, to access the parent's data context properties in your xaml:

    {Binding ThumbWidth, ElementName=LayoutRoot}

    more about doing this here.

Community
  • 1
  • 1
David Leitner
  • 3,312
  • 1
  • 18
  • 27
  • I tried, with success, adding the size parameters to the Album class, I just thought that I could accomplish the task with less redundant data... so I applied successfully your third advice! I'm going to try your prefer method Thank you David! – fernavat Aug 06 '15 at 23:09
0

Without having to add the height/width to each Album, you can use the DataContext of the ListBox (which is where the height/width) currently is.

You can do this by using a FindAncestor binding

   <Border Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.ThumbWidth}" 
           Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.ThumbHeight}">
d.moncada
  • 16,900
  • 5
  • 53
  • 82