Несколько привязок коллекции ItemsSource - PullRequest
12 голосов
/ 27 марта 2011

Как я могу связать несколько коллекций разных типов с ItemsSource элемента ItemsControl?

Использование единой привязки работает нормально:

<ItemsControl ItemsSource="{Binding Foo}" />

Но когда я пробую CompositeCollection, элементы из Foo не отображаются:

    <ItemsControl>
        <ItemsControl.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Foo}" />
            </CompositeCollection>
        </ItemsControl.ItemsSource>
    </ItemsControl>

Ответы [ 2 ]

15 голосов
/ 27 марта 2011

Я рекомендую привязать ListBox к CompositeCollection, которую вы строите в коде.В этом примере я использую ViewModel, но вы можете сделать то же самое в коде позади.Вы можете найти много примеров того, как реализовать ViewModelBase и DelegateCommand для ViewModel через google.

Вот разбивка этого примера:

  • Этот пример загружает объекты Customer и Person в дваКонтейнеры ObservableCollection для поддержки изменения коллекций.
  • ListBox связывает свой ItemsSource с CompositeCollection (ObjectCollection), которая содержит две ObservableCollections.
  • ListBox также привязывает свой SelectedItem к объекту (SelectedObject) для поддержки двух базовых типов.
  • Кнопка добавляет нового человека, чтобы показать, что вы можете изменить CompositeCollection.
  • В конце я добавил определения Клиента и Персона для полноты.

Вот вид:

<Window x:Class="StackOverflow.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">
  <Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ListBox Grid.Row="0" 
             SelectedItem="{Binding Path=SelectedObject}"
             ItemsSource="{Binding Path=ObjectCollection}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Label Content="{Binding FirstName}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button Grid.Row="1" Content="Add Person" Command="{Binding Path=AddPerson}"/>
  </Grid>
</Window>

Вот видмодель:

using System.Collections.Generic;
using System.Windows.Data;
using System.Windows.Input;
using ContextMenuNotFiring.Commands;
using ContextMenuNotFiring.Models;

namespace StackOverflow.ViewModels
{
  public class MainViewModel : ViewModelBase
  {
    public MainViewModel()
    {
      AddPerson = new DelegateCommand<object>(OnAddPerson, CanAddPerson);

      CollectionContainer customers = new CollectionContainer();
      customers.Collection = Customer.GetSampleCustomerList();

      CollectionContainer persons = new CollectionContainer();
      persons.Collection = Person.GetSamplePersonList();

      _oc.Add(customers);
      _oc.Add(persons);
    }

    private CompositeCollection _oc = new CompositeCollection();
    public CompositeCollection ObjectCollection
    {
      get { return _oc; }
    }

    private object _so = null;
    public object SelectedObject
    {
      get { return _so; }
      set
      {
       _so = value;
      }
    }

    public ICommand AddPerson { get; set; }
    private void OnAddPerson(object obj)
    {
      CollectionContainer ccItems = _oc[1] as CollectionContainer;
      if ( ccItems != null )
      {
        ObservableCollection<Person> items = ccItems.Collection as ObservableCollection<Person>;
        if (items != null)
        {
          Person p = new Person("AAAA", "BBBB");
          items.Add(p);
        }
      }
    }

    private bool CanAddPerson(object obj)
    {
      return true;
    }
  }
}

Вот модели:

public class Customer
{
  public String FirstName { get; set; }
  public String LastName { get; set; }

  public Customer(String firstName, String lastName)
  {
     this.FirstName = firstName;
     this.LastName = lastName;
  }

  public static ObservableCollection<Customer> GetSampleCustomerList()
  {
    return new ObservableCollection<Customer>(new Customer[4] {
            new Customer("Charlie", "Zero"), 
            new Customer("Cathrine", "One"),
            new Customer("Candy", "Two"),
            new Customer("Cammy", "Three")
        });
  }
}


public class Person
{
  public String FirstName { get; set; }
  public String LastName { get; set; }

  public Person(String firstName, String lastName)
  {
     this.FirstName = firstName;
     this.LastName = lastName;
  }

  public static ObservableCollection<Person> GetSamplePersonList()
  {
    return new ObservableCollection<Person>(new Person[4] {
            new Person("Bob", "Smith"), 
            new Person("Barry", "Jones"),
            new Person("Belinda", "Red"),
            new Person("Benny", "Hope")
        });
  }
}
2 голосов
/ 27 сентября 2011

Полагаю, что здесь лучше всего ответили: Как связать CollectionContainer с коллекцией в модели представления?

Это сводится к CollectionContainer, не имеющему DataContext. Вы должны установить источник так, чтобы он мог найти DataContext и завершить привязку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...