列表视图来自另一个列表视图中选择的对象的项目

时间:2010-06-15 13:53:14

标签: wpf linq-to-sql listview datacontext

好吧标题可能有点令人困惑。我有一个数据库与表公司,它与另一个表部门有一对多的关系(所以每个公司可以有很多部门),部门将有很多员工。

我有一个ListView的公司。我不想是当我从ListView中选择一家公司时,该公司内部的另一个ListView显示在它下面。然后我选择一个部门,并在该部门内的另一个员工列表视图。你得到了照片。

无论如何,主要是在XAML代码中明确地执行此操作(sp?)。我正在使用linq所以如果我理解linq正确应该包括连接到公司的部门的Division对象,那么Company实体对象具有名为Division wich的属性。因此,在获得所有公司并将它们作为itemource放到CompanyListView之后,这就是我目前所处的位置。

   <ListView x:Name="CompanyListView"
              DisplayMemberPath="CompanyName"
              Grid.Row="0" Grid.Column="0" />

    <ListView DataContext="{Binding ElementName=CompanyListView, Path=SelectedItem}"
              DisplayMemberPath="Division.DivisionName"
              Grid.Row="1" Grid.Column="0" />

我知道我已经走了,但我希望通过在DataContext和DisplayMemberPath中添加特定内容,我可以让它工作。如果没有,那么我必须捕获我猜想的公司的Id,并捕获一个选择事件或其他东西。

另一个问题但相关的是除了lisview之外的seconde列我不想拥有所选项目的详细信息/编辑视图。因此,当只有一家公司被选中时,会出现有关公司的详细信息,那么当公司的一个部门被选中时,会不会有任何想法?

2 个答案:

答案 0 :(得分:3)

您可以使用MVVM模式将XAML绑定到包含ListView信息的类,并根据选定的Comany项重置Division集合的内容。

这是一个帮助您入门的基本示例。

以下是XAML中的两个ListView控件:

<Window x:Class="MultiListView.Views.MainView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Main Window" Height="400" Width="800">
  <DockPanel>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ListView Grid.Row="0" 
                  ItemsSource="{Binding Companies}"
                  SelectedItem="{Binding Company, Mode=TwoWay}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding CompanyName}" />
                    <GridViewColumn Header="Description"
                                    DisplayMemberBinding="{Binding Description}" />
                </GridView>
            </ListView.View>
        </ListView>
        <ListView Grid.Row="1" 
                  ItemsSource="{Binding Divisions}"
                  SelectedItem="{Binding Division, Mode=TwoWay}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding DivisionName}" />
                    <GridViewColumn Header="Description"
                                    DisplayMemberBinding="{Binding Description}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
  </DockPanel>
</Window>

在代码隐藏中,将Window的DataContext设置为包含XAML中使用的绑定引用的类。

public partial class MainView : Window
{
   MainViewModel _mvm = new MainViewModel();

   public MainView()
   {
      InitializeComponent();
      DataContext = _mvm;
   }
}

以下类使用MVVM模式,您可以找到许多信息 在StackOverFlow中。该类包含XAML绑定的数据。这里 您可以使用LINQ加载/重新加载集合。

using System.Collections.ObjectModel;
using MultiListView.Models;

namespace MultiListView.ViewModels
{
public class MainViewModel : ViewModelBase
{
  public MainViewModel()
  {
     _companies = new ObservableCollection<Company>();
     _companies.Add(new Company("Stackoverflow", "QA web site"));
     _companies.Add(new Company("Fog Creek", "Agile Bug Tracking"));
     _companies.Add(new Company("Second Beach", "Not sure yet"));

     _divisions = new ObservableCollection<Division>();
  }

  private ObservableCollection<Company> _companies;
  public ObservableCollection<Company> Companies
  {
     get { return _companies; }
     set
     {
        _companies = value;
        OnPropertyChanged("Companies");
     }
  }

  private Company _company;
  public Company Company
  {
     get { return _company; }
     set
     {
        _company = value;

        // load/reload divisions for the selected company here
        LoadDivisions();

        OnPropertyChanged("Company");
     }
  }

  // hack to keep the example simpe...
  private void LoadDivisions()
  {
     _divisions.Clear();

     // use db or linq here to filiter property
     if ( _company != null )
     {
        if ( _company.CompanyName.Equals("Stackoverflow") )
        {
           _divisions.Add( new Division("QA", "Test all day"));
           _divisions.Add( new Division("Write", "Doc all day"));
           _divisions.Add( new Division("Code", "Code all day"));
        }
        else if (_company.CompanyName.Equals("Fog Creek"))
        {
           _divisions.Add(new Division("Test", "Test all day"));
           _divisions.Add(new Division("Doc", "Doc all day"));
           _divisions.Add(new Division("Develop", "Code all day"));
        }
        else if (_company.CompanyName.Equals("Second Beach"))
        {
           _divisions.Add(new Division("Engineering", "Code all day"));
        }
     }
  }

  private ObservableCollection<Division> _divisions;
  public ObservableCollection<Division> Divisions
  {
     get { return _divisions; }
     set
     {
        _divisions = value;
        OnPropertyChanged("Divisions");
     }
  }

  private Division _division;
  public Division Division
  {
     get { return _division; }
     set
     {
        _division = value;
        OnPropertyChanged("Division");
     }
  }
}
}

OnPropertyChanged实现了INotifyPropertyChanged 当ViewModel的属性发生更改时,绑定到ViewModel的Views会在ViewModel引发其PropertyChanged事件时收到通知。

您可以在大多数MVVM库中找到示例,或者查看MSDN作为示例。

答案 1 :(得分:3)

如果Divisions是公司的财产,您可能会这样做:

    <Window x:Class="MultiListView.Views.MainView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Main Window" Height="400" Width="800">
  <DockPanel>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ListView Grid.Row="0" 
                  x:Name="lvCompanies"
                  ItemsSource="{Binding Companies}"
                  SelectedItem="{Binding Company, Mode=TwoWay}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding CompanyName}" />
                    <GridViewColumn Header="Description"
                                    DisplayMemberBinding="{Binding Description}" />
                </GridView>
            </ListView.View>
        </ListView>
        <ListView Grid.Row="1" 
                  ItemsSource="{Binding ElementName='lvCompanies', Path=SelectedItem.Divisions}"
                  SelectedItem="{Binding Division, Mode=TwoWay}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding DivisionName}" />
                    <GridViewColumn Header="Description"
                                    DisplayMemberBinding="{Binding Description}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
  </DockPanel>
</Window>