Changing DataContext when another ListViewItem is selected
I've built an interface formed by a ListView and a panel with a few textboxes. In order to make change the context in those te开发者_开发知识库xtboxes when another ListViewItem is selected, I've captured the SelectionChange event, to change accordingly DataContexts of the textboxes. Something like this:
void customersList_SelectItem(object sender, SelectionChangedEventArgs e)
{
Customer customer = (Customer)customersList.Selected;
if (customer != null)
{
addressField.DataContext = customer;
phoneField.DataContext = customer;
mobileField.DataContext = customer;
webField.DataContext = customer;
emailField.DataContext = customer;
faxField.DataContext = customer;
...
}
}
Now, I wonder, is this the best the way to do it? Looks like a bit forced, but I can't devise any better.
If the textboxes were all contained in a containing element (e.g. a Grid), then you could just set the DataContext of the Grid element instead. This would be cleaner.
Even better yet would be to use XAML binding and MVVM, and this code could be implemented declaratively in XAML.
Bind the dependent controls DataContext property to the ListBox's SelectedItem property.
Or better yet if they are within a container control - Set its data context once and have the children inherit it. Something like...
<StackPanel DataContext="{Binding ElementName=ListBoxName, Path=SelectedItem}">
<!--- dependent controls -->
</StackPanel>
You can also use the "/" binding path syntax in WPF in combination with a CollectionView:
<Window ... xmlns:local="...">
<Window.DataContext>
<local:MyViewModel ... />
</Window.DataContext>
<Window.Resources>
<CollectionViewSource x:Key="ItemsView" Source="{Binding Path=Items}" />
<Window.Resources>
<ListView ItemsSource="{Binding Source={StaticResource ItemsView}}">
...
</ListView>
<Grid DataContext="{Binding Source={StaticResource ItemsView}, Path=/}">
...
</Grid>
</Window>
To quickly explain this setup:
- The window's datacontext is set to an instance of a view model
- A CollectionViewSource is created as a resource and uses a collection exposed by the view model as its source
- The listview's ItemsSource is bound directly to the CollectionView (exposed by CollectionViewSource)
- The Grid (which would contain your form elements) is bound to the CurrentItem of the CollectionView via the "/" binding path syntax; each time an item is selected in the list view, the Grid's datacontext is automatically set to the currently selected item
I prefer this type of binding over having to reference specific elemetns and properties and relying on the built in power of WPF's binding and CollectionView classes.
精彩评论