views:

106

answers:

2

I'm trying to bind my view to my view model without DataObjectProvider.

The following code runs without an error, but my ListBox is empty.

As far as I can tell, I correctly:

  • set the View's DataContext to the ViewModel itself (DataContext = new CustomersViewModel();)
  • expose the customer objects in the ViewModel (public static ObservableCollection<Customer> GetAll())
  • bind the ListBox to the customer objects (ItemsSource="{Binding GetAll}")

What little piece of syntax am I missing here?

CustomersView.xaml:

<UserControl x:Class="TestDynamicForm123.View.CustomersView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <UserControl.Resources>
        <Style x:Key="allCustomersListBox" TargetType="ListBox">
            <Setter Property="BorderThickness" Value="0"/>
        </Style>
        <DataTemplate x:Key="allCustomersDataTemplate">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding FirstName}"/>
                <TextBlock Text=" "/>
                <TextBlock Text="{Binding LastName}"/>
            </StackPanel>
        </DataTemplate>
    </UserControl.Resources>

    <StackPanel Style="{StaticResource viewWrappingStackPanel}">
        <ListBox ItemsSource="{Binding GetAll}"
                 ItemTemplate="{StaticResource allCustomersDataTemplate}"
                 Style="{StaticResource allCustomersListBox}">
        </ListBox>
    </StackPanel>
</UserControl>

CustomersView.xaml.cs:

using System.Windows.Controls;
using TestDynamicForm123.ViewModel;

namespace TestDynamicForm123.View
{
    public partial class CustomersView : UserControl
    {
        public CustomersView()
        {
            InitializeComponent();

            DataContext = new CustomersViewModel();
        }
    }
}

CustomersViewModel.cs:

using System.Collections.ObjectModel;

namespace TestDynamicForm123.ViewModel
{
    public class CustomersViewModel
    {
        public static ObservableCollection<Customer> GetAll()
        {
            return Customer.GetAll();
        }
    }
}

Customer.cs: (model)

using System.Collections.ObjectModel;

namespace TestDynamicForm123.ViewModel
{
    public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }

        public static ObservableCollection<Customer> GetAll()
        {
            ObservableCollection<Customer> customers = new ObservableCollection<Customer>();
            customers.Add(new Customer() { FirstName = "Jay", LastName = "Anders", Age = 34 });
            customers.Add(new Customer() { FirstName = "Jim", LastName = "Smith", Age = 23 });
            customers.Add(new Customer() { FirstName = "John", LastName = "Jones", Age = 22 });
            customers.Add(new Customer() { FirstName = "Sue", LastName = "Anders", Age = 21 });
            customers.Add(new Customer() { FirstName = "Chet", LastName = "Rogers", Age = 35 });
            customers.Add(new Customer() { FirstName = "James", LastName = "Anders", Age = 37 });
            return customers;
        }

    }
}
+1  A: 

The problem is that CustomersViewModel .GetAll() is a static method. Binding only works with instance properties. You should move the implementation of GetAll() to the constructor, and then expose the collection as an instance property of the class.

Andy
+1  A: 

The problem is that you are trying to bind to CustomerViewModel.GetAll(), when GetAll in CustomerViewModel is a static function not an instance property.

Change the static function to something like this (in CustomerViewModel):

public ObservableCollection<Customer> GetAll
{
    get { return Customer.GetAll(); }
}
Josh G
Exactly, thanks!
Edward Tanguay
You may want to create a singleton object to store all of the customer objects in Customer... if GetAll is read more than once, it will return a new collection of customers on each call. Another option would be to get the Customers once and save them. You could then return these customers from the GetAll property.
Josh G