如何绑定到ObservableCollection的一个元素

时间:2013-08-28 21:56:31

标签: c# wpf data-binding

我有一个ObservableCollection,并希望将Textbox绑定到该集合的特定元素。 ObservableCollection中的Items是一个实现INotifyPropertyChanged的Type。

我考虑过创建一个从ObservableCollection中选择正确元素的Property,但是当集合中的相应元素发生变化并且我不确定这是否是正确的方法时,我必须让这个属性实现此

3 个答案:

答案 0 :(得分:4)

通常,特别是如果你使用MVVM,你将拥有一个带有ObservableCollection的viewModel和一个用数据绑定更新的SelectedItem的属性。

例如,您的viewModel可能如下所示:

    class ProductsViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Product> Products { get; set; }
    private Product _selectedProduct;

    public Product SelectedProduct
    {
        get { return _selectedProduct; }
        set 
        { 
            _selectedProduct = value; 
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("SelectedProduct"));
        }
    }



    public ProductsViewModel()
    {
        Products = new ObservableCollection<Product>();
        Products.Add(new Product() { Name = "ProductA" });
        Products.Add(new Product() { Name = "ProductB" });
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

您的窗口对象xaml:

<Window x:Class="ProductsExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox HorizontalAlignment="Left" Height="171" Margin="32,29,0,0" VerticalAlignment="Top" Width="176"
                 ItemsSource="{Binding Products}"
                 SelectedItem="{Binding SelectedProduct, Mode=TwoWay}"
                 DisplayMemberPath="Name"
                 />
        <TextBox HorizontalAlignment="Left" Height="33" Margin="36,226,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="172"
                 Text="{Binding SelectedProduct.Name, Mode=TwoWay}"/>

    </Grid>
</Window>

以及您刚刚设置datacontext的代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ProductsViewModel();
    }
}

每当您在列表框中选择产品时,文本框都会使用所选产品进行更新,如果您在文本框中更改了产品(如果产品正确实现了INotifyPropertyChanged),则列表框中的项目也将更新。

显然,你只能使用代码隐藏来实现这一切,但由于以下几个原因解释: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx,最好有一个ViewModel

答案 1 :(得分:3)

如果您需要的项目是索引特定的,您可以使用索引

进行访问
 <TextBlock Text="{Binding MyItemsSource[2]}" />

答案 2 :(得分:1)

为了解决我的问题,我创建了一个Property,它从ObservableCollection中选择了正确的元素,并创建了一个事件Handler,它被添加到ObservableCollection的CollectionChanged事件中,并为SelectionProperty引发了PropertyChanged事件。

在包含ObservableCollection和SelectionProperty的类的构造函数中看起来像这样的代码:

myObservableColleciton.CollectionChanged += 
        new NotifyCollectionChangedEventHandler(
        myObservableCollection_CollectionChanged);

该类中的其他位置定义此事件处理程序:

void myObservableCollection_CollectionChanged(
        Object sender, NotifyCollectionChangedEventArgs e){
   if (PropertyChanged != null)
   {
       PropertyChanged(this, new PropertyChangedEventArgs("SelectionProperty"));
   }
}

我的selectionProperty看起来像这样:

public User SelectionProperty
{
     get { return myObservableCollection.First( user => user.id == 0); }
}

如果SelectionProperty依赖于ObservableCollection(可能我们想要找到最接近某个年龄的用户,那是在其他地方设置的),那么需要确保SelectionProperty的PropertyChanged事件也被引发,当那些其他属性改变了。