Reputation: 1646
I'm finding it challenging to get data-binding working for my sample WPF application in the MVVM style.
What's missing in the following sample?
Model: Customer
(doesn't matter actually)
ViewModel: AllCustomersViewModel
View: WizardWindowView
Exposed by VM: AllCustomers
(of type ObservableCollection)
Displayed on View: ListView
Want Binding: ListView <-> AllCustomers
<Window
...
...
<Window.Resources>
<CollectionViewSource x:Key="CustomerGroups" Source="{Binding Path=AllCustomers}"/>
</Window.Resources>
<Grid>
...
...
<aw:WizardPage Header="Step 1">
<ListView
ItemsSource="{Binding Source={StaticResource CustomerGroups}}"/>
</aw:WizardPage>
...
...
</Grid>
</Window>
I've already spent more than 10 hours trying to understand how data-binding is accomplished and feel it's time to ask for help!
Data: customers.xml
Model: Customer.cs
Data Access: CustomerRepository.cs
readonly CustomerRepository _customerRepository;
public AllCustomersViewModel(CustomerRepository customerRespository) {...}
Sequence of calls:
App.xaml.cs.OnStartup() {.. new MainWindowViewModel("Data/customers.xml")..};
public MainWindowViewModel(string customerDataFile)
{
_customerRepository = new CustomerRepository(customerDataFile);
new AllCustomersViewModel(_customerRepository);
}
In App.xaml.cs:
MainWindow window = new MainWindow();
string path = "Data/customers.xml";
var viewModel = new MainWindowViewModel(path);
window.DataContext = viewModel;
In MainWindow.xaml.cs (the codebehind):
private void ShowWizardWindow(object sender, RoutedEventArgs e)
{
Views.WizardWindowView wizardWindow = new Views.WizardWindowView();
wizardWindow.DataContext = this.DataContext;
wizardWindow.Show();
}
Upvotes: 0
Views: 321
Reputation: 1646
After assistance from several people here, from my colleague and finally from some reading, I managed to establish data-binding! Actually, a simplified one compared to what I was originally hoping.
Sorry, my answer might not be the most organized, but I'm sure it'll be understandable.
Displaying names of customers.
I have a WizardWindowView
(similar to a WPF Window) on which I wanted to display the names of customers. WizardPage
is a window (again, similar to a WPF Window) among several windows in the wizard. I also have the data-context set as in the question's edit section.
Where are the names of the customers originally coming from?
I have a data source which is an xml
file. I also have a AllCustomersViewModel.cs
class that gives an abstraction for the data in the xml file. If you want to know how the abstraction is done, you might have to do some reading on WPF! The abstraction is a collection of CustomerViewModel
objects.
Now, what are these CustomerViewModel
objects?
If AllCustomersViewModel
abstracts the collection of customer data in the original xml file, CustomerViewModel
abstracts each customer in the collection.
What is the abstraction like or what is its type?
CustomerViewModel
exposes (this is .net
jargon) a property called FirstName
of type string
. AllCustomersViewModel
exposes a property called AllCustomers
of type ObservableCollection<CustomerViewModel>
.
Now that I have the data to be displayed, I'm switching my focus to the View (xaml)
:
I'm trying to display the first names of the customers on my WizardWindowView
.
Since I have to display a list and not just one or two elements in the list, I need a xaml control to display a list (ListView
).
What should the source for ListView
be?
<ListView ItemsSource="{Binding Path=AllCustomers}">
To display each item in the list, I do the following:
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=FirstName}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
Summary:
<aw:WizardPage Header="Step 3: Edit/Check Engine (Faulty Customers)">
<ListView ItemsSource="{Binding Path=AllCustomers}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=FirstName}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</aw:WizardPage>
Upvotes: 1
Reputation: 770
In the Code-behind for the view you need to set the DataContext = ViewModel public WizardWindowView() { ... DataContext = new MainWindowViewModel(); ... } or in OnStartup() { App.MainWindow.DataContext = new MainWindowViewModel(); } Setting Window's DataContext is your missing piece.
Upvotes: 1