views:

196

answers:

2

I can't for the life of me figure out why this doesn't work. I've got a simplified piece of Xaml that looks like this:

<UserControl x:Class="Foo.MainPage" 
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&gt;
    <Grid x:Name="LayoutRoot">
        <ScrollViewer VerticalAlignment="Stretch" 
                      Background="Black" 
                      HorizontalScrollBarVisibility="Auto" 
                      VerticalScrollBarVisibility="Auto" >
            <ItemsControl x:Name="PictureItemsControl"
                          ItemsSource="{Binding Pics}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" 
                                    VerticalAlignment="Center" 
                                    HorizontalAlignment="Center" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <Image Source="{Binding Location}" 
                                   Height="200" 
                                   Width="200" 
                                   Stretch="UniformToFill" />
                            <TextBlock FontFamily="Verdana" 
                                       FontSize="16" 
                                       Foreground="White" 
                                       Text="{Binding Name}" />
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</UserControl>

In the codebehind for my MainPage.xaml, I have this:

namespace Foo
{
    public partial class MainPage : UserControl
    {
        public FooViewModel viewModel;

        public MainPage()
        {
            InitializeComponent();
            viewModel = new FooViewModel();
            this.DataContext = viewModel;
        }

    }
}

And my ViewModel looks like this:

namespace Foo
{
    public class FooViewModel:INotifyPropertyChanged
    {
        public ObservableCollection<Pic> Pics;
        public FooViewModel()
        {
            Pics = new ObservableCollection<Pic>();
            Pic.GetPics(Pics);
        }

        //More code here... 
    }
}

And Pic is just a simple class that has some public properties and a static method that fills an observable collection with test data. The problem is that I'm not seeing any binding happening in my ItemsControl UNLESS I add this line to my MainPage constructor:

PictureItemsControl.ItemsSource = viewModel.Pics;

If I do that, the binding works. But this doesn't seem right to me. Am I missing something in the declarative binding?

A: 

Yes, you need to specify the ItemsSource on an ItemControl (ListBox, TabControl, ComboBox) to be able to bind data to it.

xamlgeek
I don't understand your response. I can bind to the ItemsSource in code, but the equilivent line of Xaml doesn't seem to work. Can you be more specific about what I'm not including in the xaml?
Raumornie
+3  A: 

You need to change "Pics" to be a property, not a field. You cannot directly databind to a field. Change Pics to:

public ObservableCollection<Pic> Pics { get; private set; }

The working case works because you're binding to your ViewModel, and Pics indirectly.

Reed Copsey
Thanks! I figured it had to be something easy and I must have overlooked that in the docs.
Raumornie