2013-09-06 4 views
0

Последний вопрос дня.Сопоставление данных на нескольких уровнях

Я новичок в моделировании MVVM и достиг совершеннолетия с моим пониманием этого, но мне понадобилось бы руководство по чему-то, прежде чем я вверну свой весь проект, возившись вокруг.

Я создал модель с именем человека, который ниже:

- General info like: ID, FirstName, LastName, FullName, Nationality etc. 
- A list of old jobs 
- Each job (a separate model) within the old jobs list has data as well such as YearStarted, YearEnded, Occupation, Company etc. 

Так что моя модель выглядит следующим образом:

- Person: 
    - ID 
    - Name 
    - Nationality 
    - Jobs: 
      - Job1: 
       - Occupation 
       - Started 
       - Ended 
       - Salary 
       - Duties: 
        - Duties 1 
        - Duties 2 
      - Job2: 
       - Occupation 
       - Started 
       - Ended 
       - Salary 
       - Duties: 
        - Duties 1 
        - Duties 2 
        - Duties 3 

На мой взгляд, список людей, показывает отлично. Когда я нажимаю на одного из людей, я открываю новую страницу WPF с собственным контролем. Я создал конструктор с именем ClickedPerson, который извлекает данные модели Person человека, которого щелкнули. Работает отлично, и я могу показать данные первого уровня, такие как имя человека путем привязки как такового: {Binding Path = ClickedPerson.Name}

Мой вопрос: как я могу иметь элемент ItemsControl, который будет показывать уровень 2 и уровень 3 данных этого человека? Смысл, если бы я должен был внедрить элемент ItemsControl, где бы была стекная панель с 1 новым UserControl (например) для каждого OldJob в жизни человека, а затем, чтобы дочерние элементы UserControl отображали конкретные данные старой работы, такие как Занятие или Зарплата в текстовых окнах => Как написать обязательную часть в XAML?

Не беспокойтесь о пользовательском интерфейсе, я могу справиться с этим, это просто связанная часть, о которой я не знаю.

Позвольте мне знать, если я объяснил, как слепая горилла ...

UPDATE: Так с тем, что вы, ребята, говорят, я написал связывание ниже простой пользовательский интерфейс, но он не показывает ничего. Что я делаю не так?

   <TreeView Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="3" 
           ItemsSource="{Binding Path=ClickedPerson}"> 
        <!-- List of OldJobs teamplate --> 
        <TreeView.ItemTemplate> 
         <HierarchicalDataTemplate ItemsSource="{Binding Duties}"> 
          <TextBlock Foreground="White" Text="{Binding JobNumber}" /> 

          <!-- Job template --> 
          <HierarchicalDataTemplate.ItemTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Occupation}" /> 
           </DataTemplate> 
          </HierarchicalDataTemplate.ItemTemplate> 
         </HierarchicalDataTemplate> 
        </TreeView.ItemTemplate> 
       </TreeView> 

UPDATE 2: Я не получаю это я ??

Я написал это в моем ViewModel и видом на основе того, что я прочитал, и что вы, ребята сказали ... Думал, что это будет работать, но ничего не показывает в моем Treeview:

private Person _clickedPerson; 
public CollectionViewSource ClickedPersonJobs { get; set; } 

public Person ClickedPerson 
     { 
      get { return _clickedPerson; } 
      set 
      { 
       _ clickedPerson = value; 
       ClickedPersonJobs = new CollectionViewSource(); 
       ClickedPersonJobs.SortDescriptions.Add(new SortDescription("JobNumber", ListSortDirection.Ascending)); 
       ClickedPersonJobs.GroupDescriptions.Add(new PropertyGroupDescription("JobNumber")); 
       ClickedPersonJobs.Source = _ clickedPerson.OldJobs; 
       NotifyOfPropertyChange(() => ClickedPerson); 
      } 
     } 

и на мой взгляд, XAML-файл:

<TreeView ItemsSource="{Binding ClickedPersonJobs }" 
            Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="3"> 

          <!-- Job teamplate --> 
          <TreeView.ItemTemplate> 
           <HierarchicalDataTemplate ItemsSource="{Binding Duties}"> 
            <TextBlock Foreground="Red" Text="{Binding Occupation}" /> 

            <!-- Duties template --> 
            <HierarchicalDataTemplate.ItemTemplate> 
             <DataTemplate> 
              <TextBlock Text="{Binding Description}" /> 
             </DataTemplate> 
            </HierarchicalDataTemplate.ItemTemplate> 

           </HierarchicalDataTemplate> 
          </TreeView.ItemTemplate> 

         </TreeView> 
+0

Я думаю, что это должно работать при условии 'ClickedPerson' коллекция вашей модели' Person' – AsitK

+0

Я думаю, вам нужно указать тип данных для шаблона – AsitK

+0

Я надеюсь, что Вы установили DataContext вида ViewModel ..;) – AsitK

ответ

0

Вы можете использовать TreeView для WPF. HierarchialDataTemplate поможет вам здесь.

для простого exmaple см MSDN enter link description here

<HierarchicalDataTemplate DataType = "{x:Type src:League}" 
          ItemsSource = "{Binding Path=Divisions}"> 
    <TextBlock Text="{Binding Path=Name}"/> 
    </HierarchicalDataTemplate> 

    <HierarchicalDataTemplate DataType = "{x:Type src:Division}" 
          ItemsSource = "{Binding Path=Teams}"> 
    <TextBlock Text="{Binding Path=Name}"/> 
    </HierarchicalDataTemplate> 

    <DataTemplate DataType="{x:Type src:Team}"> 
    <TextBlock Text="{Binding Path=Name}"/> 
    </DataTemplate> 

Это показывает иерархию 3 уровня.

League 
    Division 
     Team 

Ключ использовать ItemsSource из HierarchicalDataTemplate и обеспечения правильного DataTemplate для каждого.

0

Это не проблема MVVM, а проблема с синтаксисом пути Binding. Таким образом, вы можете просмотреть страницу Binding.Path Property в MSDN.

От связанной страницы:

Когда источник представляет собой вид коллекции, текущий элемент может быть задан с косой чертой (/). Например, предложение Path =/устанавливает привязку к текущему элементу в представлении. Когда источником является коллекция, этот синтаксис определяет текущий элемент представления коллекции по умолчанию.

В основном, это означает, что вы можете использовать следующую Binding для отображения Occupation выбранного Job от выбранного Person:

{Binding PersonCollection/JobCollection/Occupation} 
0

У меня есть пример, где я есть что-то, как вы, но с Buttongroups и Buttons (вместо ваших Рабочих мест и Job1, Job2, ... Итак, в моем ViewModel у меня есть свойство ObservableCollection<ButtonGroups> Groups. My ButtonGroups-Model имеет строку GroupName и ObservableCollection с кнопками, где я объявляю LabelString и ButtonCommand.

Мой ItemsControl выглядит следующим образом:

<ItemsControl x:Name="Groups" ItemsSource="{Binding Groups}"> 
<ItemsControl.ItemTemplate> 
<DataTemplate>   
    <GroupBox Header="{Binding Path=GroupName}"> 
     <ItemsControl ItemsSource="{Binding Buttons}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
      <Button Content="{Binding Path=LabelString}" Command="{Binding Path=ButtonCommand}"/> 
      </DataTemplate> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
      <StackPanel x:Name="BtnStackPanel" Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
     <ItemsControl.ItemsPanel> 
     </ItemsControl> 
    </GroupBox> 
</DataTemplate> 
</ItemsControl.ItemTemplate> 
<ItemsControl.ItemsPanel> 
<ItemsPanelTemplate> 
    <StackPanel x:Name="GroupStackPanel" Orientation="Horizontal"/> 
</ItemsPanelTemplate> 
<ItemsControl.ItemsPanel> 

Это дает мне ряд кнопок, которые я определил. Таким образом, у меня есть 1 ItemsControl для каждой кнопки. Вы можете изменить свой ItemsControl, чтобы иметь свои Работы и свойства каждого задания, которое вы хотите показать.

Вот мой вопрос, где я получил, что: Link

Надежда, что помогает.

0

Здесь вы можете указать DataGrid, в котором будет указан PersonItemsSource. Как только вы это сделаете, каждый DataGridRow будет иметь объект Person в качестве своего DataContext. Теперь вы можете иметь столбцы в DataGrid, связанные с свойствами Person.

Затем вы можете определить RowDetailsTemplate, чтобы отобразить иерархические данные. Вы можете установить для параметра rowtemplate значение DataGrid, чтобы показать задания в нем. Поскольку DataContext для этого datagrid также будет объектом Person, вы можете привязать его к JobList внутри человека, чтобы заполнить его данные. Аналогичным образом вы можете иметь несколько иерархий.

 <DataGrid ItemsSource="{Binding PersonList}"> 
      <DataGrid.Columns> 
       <DataGridTextColumn IsReadOnly="True" Binding="{Binding FirstName}"/> 
       <DataGridTextColumn IsReadOnly="True" Binding="{Binding LastName}"/> 
       <DataGridTextColumn IsReadOnly="True" Binding="{Binding FullName}"/> 
      </DataGrid.Columns> 
      <DataGrid.RowDetailsTemplate> 
       <DataTemplate> 
        <DataGrid ItemsSource="{Binding Jobs}"> 
         <DataGrid.Columns> 
          <DataGridTextColumn IsReadOnly="True" Binding="{Binding Occupation}"/> 
          <DataGridTextColumn IsReadOnly="True" Binding="{Binding Started}"/> 
          <DataGridTextColumn IsReadOnly="True" Binding="{Binding Salary}"/> 
         </DataGrid.Columns> 
        </DataGrid> 
       </DataTemplate> 
      </DataGrid.RowDetailsTemplate> 
     </DataGrid> 

Благодаря

Смежные вопросы