Вложенная привязка данных с помощью WPF и C # - PullRequest
1 голос
/ 22 июня 2011

Я пытаюсь составить бюджетную программу. Где мне нужно иметь групповые блоки со списком текстовых блоков внутри.

<ItemsControl DataContext="{Binding}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <GroupBox Header="{Binding}">
        <ItemsControl DataContext="{Binding}">
          <ItemsControl.ItemTemplate>
            <DataTemplate>
              <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Text}" />
                <TextBlock Text="{Binding Value}" />
              </StackPanel>
            </DataTemplate>
          </ItemsControl.ItemTemplate>
        </ItemsControl>
      </GroupBox>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

Мне нужно каким-то образом связать список (возможно?) С групповыми блоками, чтобы я создал список групповых блоков с некоторыми строками внутри, который был бы текстом со значением валюты. Чтобы я мог создать группу под названием «Квартира» с двумя строками «Аренда $ 3000» и «Обслуживание $ 150». Тогда я мог бы иметь вторую группу под названием «Автомобиль», например, со строками «Страхование», «Кредит» и «Техническое обслуживание».

Но как мне связать это? И как бы мне нужно в C # для этого. Я в растерянности.

Ответы [ 2 ]

5 голосов
/ 22 июня 2011

Основываясь на комментариях Джея, вы захотите создать иерархическую модель данных. Примечание. Я оставил вам реализацию INotifyPropertyChanged в свойствах

public class BudgetLineItem : INotifyPropertyChanged
{
   public string Name { get; set; }
   public decimal Cost { get; set; }
}

public class BudgetGroup : INotifyPropertyChanged
{
   public string GroupName { get; set; }
   public ObservableCollection<BudgetLineItem> LineItems { get; set; }
}

public class BudgetViewModel : INotifyPropertyChanged
{
   public ObservableCollection<BudgetGroup> BudgetGroups { get; set; }
}

Тогда ваш шаблон данных будет выглядеть так:

<ItemsControl DataContext="{Binding ViewModel}"
              ItemsSource="{Binding BudgetGroups}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <GroupBox Header="{Binding GroupName}">
        <ItemsControl ItemsSource="{Binding LineItems}">
          <ItemsControl.ItemTemplate>
            <DataTemplate>
              <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding Cost}" />
              </StackPanel>
            </DataTemplate>
          </ItemsControl.ItemTemplate>
        </ItemsControl>
      </GroupBox>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
0 голосов
/ 23 июня 2011

Я мог бы быть неосновным здесь, но звучит так, как будто вы хотите изменить DataTemplate в зависимости от типа объекта, который связан из списка разнородных объектов.

Если это так, вы хотитепосмотреть на DataTemplateSelectors или создать DataTemplates для каждого из типов, которые вы хотите поддерживать в списке.

Например, для квартиры у вас может быть:

<DataTemplate DataType="local:ApartmentBudget">
  <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Text}" />
    <TextBlock Text="{Binding Value}" />
  </StackPanel>
</DataTemplate>

Автомобиль может выглядеть так:

<DataTemplate DataType="local:CarBudget">
  <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Insurance}" />
    <TextBlock Text="{Binding Loan}" />
    <TextBlock Text="{Binding Maintenance}" />
  </StackPanel>
</DataTemplate>

Тогда ваш ItemsControl может быть настроен следующим образом:

<ItemsControl ItemSource="{Binding BudgetItems}">

Правильный шаблон данных будет выбран в зависимости от типа данных.Вы можете получить еще больший контроль, создав собственный DataTemplateSelector.

См. https://msdn.microsoft.com/en-us/library/ms742521(v=vs.100).aspx для получения дополнительной информации.

...