Recomiendo vinculante ListBox a un CompositeCollection que construyes en código En este ejemplo, estoy usando un ViewModel, pero también puede hacer lo mismo en un código subyacente. Puede encontrar muchos ejemplos sobre cómo implementar ViewModelBase y DelegateCommand para ViewModel a través de google.
Aquí está el desglose de este ejemplo:
- Este ejemplo carga de Cliente y Persona objetos en dos recipientes ObservableCollection para apoyar la modificación de las colecciones.
- ListBox vincula su ItemsSource a CompositeCollection (ObjectCollection) que contiene dos ObservableCollections.
- ListBox también vincula su SelectedItem a un objeto (SelectedObject) para admitir dos tipos de base.
- El botón agrega una nueva persona para mostrar que puede modificar CompositeCollection.
- He añadido definiciones de cliente y persona al final para que estén completas.
Aquí es la vista:
<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>
Aquí es el modelo de vista:
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;
}
}
}
Éstos son los modelos:
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")
});
}
}
¿Cuál es la ventaja de crear CompositeCollection en el código subyacente/VM en lugar de hacerlo en XAML con CollectionContainer vinculado a las propiedades respectivas de VM? – SOReader