Просмотр списка элементов из объекта, выбранного в другом просмотре списка - PullRequest
3 голосов
/ 15 июня 2010

Хорошо, название может быть немного запутанным.У меня есть база данных с таблицей Companies, которая имеет отношение «один ко многим» с другой таблицей Divisions (так что в каждой компании может быть много подразделений), и в подразделении будет много сотрудников.

У меня есть ListView компаний.Я не хочу, чтобы, когда я выбираю компанию из ListView, под ней появляется другое ListView подразделений в этой компании.Затем я выбираю подразделение и еще один список сотрудников в этом отделе.Вы получаете картину.

В любом случае можно ли делать это в основном в коде XAML в упрощенном порядке (sp?).Я использую linq, поэтому объекты сущностей Компании имеют свойство с именем Division, которое, если я правильно понимаю, linq должно включать объекты Division подразделений, связанных с компанией.Поэтому после получения всех компаний и размещения их в качестве источника элементов в 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, я не хочу иметь подробности /редактировать вид для выбранного элемента.Так что, когда будет выбрана только компания, подробности об этом появятся тогда, когда будет выбрано подразделение в компании. Это пойдет вместо этого, какие-нибудь идеи?

Ответы [ 2 ]

3 голосов
/ 15 июня 2010

Если Division является собственностью компании, вы, вероятно, могли бы сделать что-то вроде этого:

    <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>
3 голосов
/ 15 июня 2010

Вы можете использовать шаблон MVVM, чтобы связать свой XAML с классом, который содержит информацию для ваших ListViews, и сбросить содержимое коллекции Division на основе выбранного элемента Comany.

Вот базовый пример для получениявы начали.

Вот два элемента управления ListView в XAML:

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

В выделенном фрагменте кода установите DataContext для Window для класса, который содержит ссылки на привязки, используемые в 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, получают уведомление, когда ViewModelвызывает событие PropertyChanged.

Примеры можно найти в большинстве библиотек MVVM, или посмотрите MSDN для примера.

...