In WPF how can I bind to the ViewModel and have various XAML elements bind to the ViewModel's methods?

StackOverflow https://stackoverflow.com/questions/801889

  •  03-07-2019
  •  | 
  •  

Question

I can bind a ListBox like this:

XAML:

<UserControl x:Class="TestDynamicForm123.Views.ViewCustomers"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Margin="10">
        <ListBox ItemsSource="{Binding}"/>
    </StackPanel>
</UserControl>

Code Behind:

using System.Windows.Controls;
using TestDynamicForm123.ItemTypes;

namespace TestDynamicForm123.Views
{
    public partial class ViewCustomers : UserControl
    {
        public ViewCustomers()
        {
            InitializeComponent();

            DataContext = Customers.GetAll();
        }
    }
}

View Model:

using System.Collections.ObjectModel;

namespace TestDynamicForm123.ItemTypes
{
    class Customers : ItemTypes
    {
        protected ObservableCollection<Customer> collection;

        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;
        }
    }
}

But how do I "move it up a level" so I can in the code behind bind to Customers itself and within my XAML bind to Customers various methods, e.g. GetAll() for a ListBox and GetBest() for another control, etc.?

I tried it with this syntax in the code behind:

DataContext = new Customers();

And these two syntaxes in the XAML but neither work:

<ListBox ItemsSource="{Binding GetAll}"/> (returns blank ListBox)
<ListBox ItemsSource="{Binding Source={StaticResource GetAll}}"/> (returns error)
Was it helpful?

Solution

You need to use ObjectDataProvider to bind to methods, but that should be the exception rather than the norm. Usually your VM would just expose properties that you bind to, including a property that exposes all relevant Customers.

OTHER TIPS

You need to create a view model class (CustomersViewModel) for your view. CustomersViewModel will expose the data and the command (ICommand interface) via properties that your view (ViewCustomers) can bind to. You can then set DataContext of ViewCustomers to an instance of CustomersViewModel. Check out the following MSDN article on Model-View-ViewModel pattern in WPF.

WPF Apps With The Model-View-ViewModel Design Pattern

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top