选择另一个ListViewItem时更改DataContext



我构建了一个由ListView和一个带有几个文本框的面板组成的界面。为了在选择另一个ListViewItem时更改这些文本框中的上下文,我捕获了SelectionChange事件,以相应地更改文本框的DataContexts。类似这样的东西:

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

现在,我想知道,这是最好的方法吗?看起来有点勉强,但我想不出更好的办法了。

如果文本框都包含在一个包含元素(例如Grid)中,那么您可以改为设置Grid元素的DataContext。这会更干净。

更好的方法是使用XAML绑定和MVVM,并且可以在XAML中以声明方式实现此代码。

将依赖控件DataContext属性绑定到ListBox的SelectedItem属性。

或者更好的是,如果它们在容器控件中-设置一次其数据上下文并让子代继承它。。。

<StackPanel DataContext="{Binding ElementName=ListBoxName, Path=SelectedItem}">
   <!--- dependent controls -->
</StackPanel>

您还可以将WPF中的"/"绑定路径语法与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>

要快速解释此设置:

  • 窗口的datacontext设置为视图模型的实例
  • CollectionViewSource被创建为资源,并使用视图模型公开的集合作为其源
  • 列表视图的ItemsSource直接绑定到CollectionView(由CollectionViewSource公开)
  • 网格(包含表单元素)通过"/"绑定路径语法绑定到CollectionView的CurrentItem;每次在列表视图中选择项目时,网格的数据上下文都会自动设置为当前选择的项目

我更喜欢这种类型的绑定,而不是必须引用特定的元素和属性,并依赖WPF的绑定和CollectionView类的内置功能。

最新更新