【问题标题】:Listview of items from a object selected in another listview在另一个列表视图中选择的对象的项目列表视图
【发布时间】:2010-06-15 13:53:14
【问题描述】:

好的,标题可能有点混乱。我有一个包含表 Companies 的数据库,该表与另一个表 Divisions 具有一对多的关系(因此每个公司都可以有许多部门),并且部门将有很多员工。

我有公司的 ListView。我不想要的是,当我从 ListView 中选择一家公司时,该公司内的另一个 ListView 会出现在它的下方。然后我选择一个部门,该部门内的另一个员工列表视图出现在其下方。你明白了。

无论如何,主要在 XAML 代码中以声明方式执行此操作(sp?)。我正在使用 linq,因此 Company 实体对象有一个名为 Division 的属性,如果我正确理解 linq,它应该包括与公司连接的部门的 Division 对象。因此,在获得所有公司并将它们作为 itemsource 到 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 之外的第二列中,我不想为所选项目提供详细信息/编辑视图。因此,当只选择公司的详细信息时,就会出现有关该公司的划分时会出现的,它将转移到那里,任何想法?

【问题讨论】:

    标签: wpf linq-to-sql listview datacontext


    【解决方案1】:

    您可以使用 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 的 View 会在 ViewModel 引发其 PropertyChanged 事件时收到通知。

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

    【讨论】:

    • 这个 OnPropertyChanged 方法是从哪里来的,它的作用是什么?
    • 我在答案末尾添加了有关 OnPropertyChanged 的​​更多详细信息。
    • 好的,动态详细信息框显示公司/部门/员工的详细信息,具体取决于所选人员。我也应该看看 TreeView 吗?
    • 对于详细信息框,您可以将其他控件添加到现有视图或创建绑定到视图模型中所选项目的不同视图。如果您引入树视图,请记住使用带有左窗格(树视图)和右窗格(网格/列表)的 Windows 资源管理器的体验。网格/列表倾向于为用户提供更好的选择和浏览体验。
    【解决方案2】:

    如果 Divisions 是 Company 的财产,您可以这样做:

        <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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 2013-09-18
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多