多收集的ItemsSource绑定 [英] Multiple ItemsSource collection bindings

查看:128
本文介绍了多收集的ItemsSource绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何能结合不同类型的多个集合到一个ItemsControl的ItemsSource的



使用单一的绑定工作正常:

 <的ItemsControl的ItemsSource ={结合美孚}/> 



但是,当我尝试CompositeCollection,从中显示:

 <&ItemsControl的GT; 
< ItemsControl.ItemsSource>
< CompositeCollection>
< CollectionContainer收集={结合美孚}/>
< / CompositeCollection>
< /ItemsControl.ItemsSource>
< / ItemsControl的>


解决方案

我建议绑定列表框为您打造一个CompositeCollection在代码中。
在这个例子中,我使用一个ViewModel,但你可以做同样的隐藏代码。
你可以找到如何通过谷歌实施ViewModelBase和DelegateCommand的视图模型许多例子



下面是这个例子的细分:




  • 此示例加载客户和Person对象分为二的ObservableCollection容器支持修改的集合。

  • 列表框绑定其的ItemsSource到CompositeCollection(ObjectCollection),它包含两个ObservableCollections。

  • 列表框也结合了的SelectedItem一个对象(SelectedObject)支持两种基本类型。

  • 的按键增加了一个新的人给你看可以修改CompositeCollection。

  • 我在最后的完整性新增客户和个人defintitions。



下面是查看:

 <窗​​口x:类=StackOverflow.Views.MainView
的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/presentation
的xmlns:X = http://schemas.microsoft.com/winfx/2006/xaml
标题=主窗口HEIGHT =400WIDTH =800>
<网格和GT;
< Grid.RowDefinitions>
< RowDefinition />
< RowDefinition高度=自动/>
< /Grid.RowDefinitions>
<列表框Grid.Row =0
的SelectedItem ={绑定路径= SelectedObject}
的ItemsSource ={绑定路径= ObjectCollection}>
< ListBox.ItemTemplate>
<&DataTemplate的GT;
<标签内容={结合姓}/>
< / DataTemplate中>
< /ListBox.ItemTemplate>
< /列表框>
<按钮Grid.Row =1CONTENT =加人命令={绑定路径= addPerson的}/>
< /网格和GT;
< /窗GT;

下面是视图模型:

 使用System.Collections.Generic; 
使用System.Windows.Data;
使用System.Windows.Input;使用ContextMenuNotFiring.Commands
;使用ContextMenuNotFiring.Models
;

命名空间StackOverflow.ViewModels
{
公共类MainViewModel:ViewModelBase
{
公共MainViewModel()
{
addPerson的=新DelegateCommand<对象>(OnAddPerson,CanAddPerson);

CollectionContainer客户=新CollectionContainer();
customers.Collection = Customer.GetSampleCustomerList();

CollectionContainer人员=新CollectionContainer();
persons.Collection = Person.GetSamplePersonList();

_oc.Add(客户);
_oc.Add(人);
}

私人CompositeCollection _oc =新CompositeCollection();
公共CompositeCollection ObjectCollection
{
{返回_oc; }
}

私有对象_so = NULL;
公共对象SelectedObject
{
{返回_so; }

{
_so =价值;
}
}

公众的ICommand addPerson的{搞定;组; }
私人无效OnAddPerson(obj对象)
{
CollectionContainer ccItems = _oc [1] CollectionContainer;
如果(ccItems!= NULL)
{
&的ObservableCollection LT;人>项目= ccItems.Collection作为的ObservableCollection<人取代;
如果(项目!= NULL)
{
者P =新的Person(AAAA,BBBB);
items.Add(对);
}
}
}

私人布尔CanAddPerson(obj对象)
{
返回真;
}
}
}

下面是模式:

 公共类客户
{
公共字符串名字{搞定;组; }
公共字符串名字{搞定;组; }

公众客户(字符串名字,字符串的lastName)
{
this.FirstName =名字;
this.LastName = lastName的;
}

公共静态的ObservableCollection<客户> GetSampleCustomerList()
{
返回新的ObservableCollection<客户>(新客户[4] {
新的客户(查理,零),
新的客户(Cathrine ,一),
新的客户(糖果,二),
新的客户(CAMMY,三)
});
}
}


公共类Person
{
公共字符串名字{搞定;组; }
公共字符串名字{搞定;组; }

公众人物(字符串名字,字符串的lastName)
{
this.FirstName =名字;
this.LastName = lastName的;
}

公共静态的ObservableCollection<&人GT; GetSamplePersonList()
{
返回新的ObservableCollection<人>(新的Person [4] {
新的Person(鲍勃,史密斯),
新的Person(巴里,奇兵),
新的人(贝琳达,红),
新的人(本尼,希望)
});
}
}


How can I binds multiple collections of different types to an ItemsSource of an ItemsControl?

Using a single binding works fine:

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

But when I try a CompositeCollection, the items from Foo aren't displayed:

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

解决方案

I recommend binding the ListBox to a CompositeCollection that you build in code. In this example I am using a ViewModel, but you can do the same in a code-behind as well. You can find many examples on how to implement ViewModelBase and DelegateCommand for the ViewModel via google.

Here is the breakdown of this example:

  • This example loads Customer and Person objects into two ObservableCollection containers to support modifying the collections.
  • The ListBox binds its ItemsSource to the CompositeCollection (ObjectCollection) which contains two ObservableCollections.
  • The ListBox also binds its SelectedItem to an object (SelectedObject) to support two base types.
  • The Button adds a new Person to show you can modify the CompositeCollection.
  • I added Customer and Person defintitions at the end for completeness.

Here is the View:

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

Here is the ViewModel:

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

Here are the models:

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")
        });
  }
}

这篇关于多收集的ItemsSource绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆