简体   繁体   中英

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

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 , eg 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)

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 Customer s.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM