将ComboBox绑定到ObservableCollection的一部分

时间:2014-03-11 23:49:38

标签: c# wpf data-binding combobox

我在C#中有一个WPF应用程序,其中有一个类MyCollection的对象扩展ObservableCollection<MyType>,它保存项目以便将它们绑定到几个ComboBox。

但是,每个ComboBox必须显示此集合的子集(基于其元素的某个属性),并且可能会根据用户输入而更改。

如何使用原始集合中的数据更新每个子集,从而获得此行为?这种情况是否有一些众所周知的设计模式?


编辑:由于我对此问题的表述很容易被误解,所以这是一个例子。 我有一个ObservableCollection<Person>对象,其中类Person具有AgeName属性。 我有三个组合框,前两个必须显示Name Person个{奇异Age个对象,而第三个必须显示偶数Age。他们的角色可能会在运行时改变(例如,第一个和最后一个必须显示奇数年龄,第二个甚至年龄) 如果在集合中添加或删除Person个对象,则必须在相应的ComboBox上反映更改。 NameAge属性可能会被视为不变。

1 个答案:

答案 0 :(得分:2)

如果我理解你的问题,你需要某种过滤机制。

查看ICollectionView界面及其实现,例如CollectionViewSource,可能有助于您实现此目标。

您需要处理实现过滤逻辑的Filter事件。

以下是MSDN上的课程(http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource(v=vs.110).aspx

一个例子:

容器类:

public string Name { get; set; }
public string Capital { get; set; }

public Country(string name, string capital) {
    this.Name = name;
    this.Capital = capital;
}

模特课:

private ObservableCollection<Country> _countries;
private ICollectionView _european;
private ICollectionView _american;

public ObservableCollection<Country> Countries {
    get {
        if (_countries == null) {
            _countries = new ObservableCollection<Country>();
        }

        return _countries;
    }
}

public ICollectionView European {
    get {
        if (_european == null) {
            _european = new CollectionViewSource {
                Source = this.Countries
            }.View;
            _european.Filter += (e) => {
                Country c = e as Country;
                if (c.Name == "UK" || c.Name == "Ireland" || c.Name == "France") {
                    return true;
                }

                return false;
            };
        }

        return _european;
    }
}

public ICollectionView American {
    get {
        if (_american == null) {
            _american = new CollectionViewSource {
                Source = this.Countries
            }.View;
            _american.Filter += (e) => {
                Country c = e as Country;
                if (c.Name == "USA" || c.Name == "Canada" || c.Name == "Mexico") {
                    return true;
                }

                return false;
            };
        }

        return _american;
    }
}

初始化代码:

private Model _model;

public Model Model {
    get {
        if (_model == null) {
            _model = new Model();
        }

        return _model;
    }
}

public MainWindow() {
    InitializeComponent();
    this.DataContext = this.Model;
    this.Model.Countries.Add(new Country("UK", "London"));
    this.Model.Countries.Add(new Country("Ireland", "Dublin"));
    this.Model.Countries.Add(new Country("France", "Paris"));
    this.Model.Countries.Add(new Country("USA", "Washington D. C."));
    this.Model.Countries.Add(new Country("Mexico", "Mexico City"));
    this.Model.Countries.Add(new Country("Canada", "Ottawa"));
}

XAML:

<StackPanel>
    <ComboBox
        ItemsSource='{Binding Path=European}'>
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel
                    Orientation='Horizontal'>
                    <TextBlock
                        Text='{Binding Path=Name}' />
                    <TextBlock
                        Text=', ' />
                    <TextBlock
                        Text='{Binding Path=Capital}' />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

    <ComboBox
        ItemsSource='{Binding Path=American}'>
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel
                    Orientation='Horizontal'>
                    <TextBlock
                        Text='{Binding Path=Name}' />
                    <TextBlock
                        Text=', ' />
                    <TextBlock
                        Text='{Binding Path=Capital}' />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
</StackPanel>