将viewmodel中的ObservableCollection绑定到列表框

时间:2015-05-18 21:21:36

标签: c# wpf mvvm binding viewmodel

我对MVVM和绑定非常陌生,我试图学会使用它。 我遇到了将viewmodel绑定到视图的问题,特别是将可观察集合绑定到列表框。

这是我的viewmodel的样子:

namespace MyProject
{
    using Model; 

public class NetworkViewModel: INotifyPropertyChanged
{

    private ObservableCollection<Person> _networkList1 = new ObservableCollection<Person>();
    public ObservableCollection<Person> NetworkList1 //Binds with the listbox
    {
        get { return _networkList1; }
        set { _networkList1 = value; RaisePropertyChanged("_networkList1"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public NetworkViewModel() 
    {
        _networkList1 = new ObservableCollection<Person>()
        {
            new Person(){FirstName="John", LastName="Doe"},
            new Person(){FirstName="Andy" , LastName="Boo"}
        };
   }
}

在我的视图中

namespace MyProject
{
    public partial class Networking : Window
    {

        public Networking()
       {
            InitializeComponent();

            this.DataContext = new NetworkViewModel();

            lb1.ItemsSource = _networkList1;
        }
     }
}  

在XAML中我有

<ListBox x:Name="lb1" HorizontalAlignment="Left" ItemsSource="{Binding NetworkList1}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock >
                         <Run Text="{Binding Path=FirstName}"/>
                         <Run Text="{Binding Path=LastName}"/>
                    </TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

3 个答案:

答案 0 :(得分:2)

您的视图模型中可能会出现拼写错误。

RaisePropertyChanged("_networkList1");

您想要为公共属性而不是私有变量引发属性更改通知。

RaisePropertyChanged("NetworkList1");

这可能会阻止您的观点正确更新。

答案 1 :(得分:1)

除了Gaurav的回答,如果_networkList1类是NetworkViewModel类中的私有字段,那么如何在Networking窗口中访问它?我的意思是下一行的含义是什么?

lb1.ItemsSource = _networkList1;

当您定义属性NetworkList1)时,您必须使用才能获得其功能(例如获取{{1}工作)。除此之外,您可以刚刚定义了一个字段(RaisePropertyChanged)。如此改变

_networklist1

_networkList1 = new ObservableCollection<Person>()

导致实际设置NetworkList1 = new ObservableCollection<Person>() ,因此NetworkList1被触发。 (但是,如果您只想在列表框中显示数据,则这是不必要的)

如果我做对了,请改变这个:

RaisePropertyChanged("NetworkList1")

public partial class Networking : Window
{

    public Networking()
   {
        InitializeComponent();

        this.DataContext = new NetworkViewModel();

        lb1.ItemsSource = _networkList1;
    }
 }

应该让你的绑定工作。

*请注意,当您将 public partial class Networking : Window { public NetworkViewModel MyViewModel { get; set; } public Networking() { InitializeComponent(); MyViewModel = new NetworkViewModel(); this.DataContext = MyViewModel; } } 设置为DataContext时,

中的绑定
NetworkViewModel

有效,因为<ListBox x:Name="lb1" HorizontalAlignment="Left" ItemsSource="{Binding NetworkList1}"> NetworkList1的属性。

答案 2 :(得分:0)

出于上帝的考虑,请勿在{{1​​}}上调用RaisePropertyChanged()方法。这是大多数情况下的常见错误(但是,在某些情况下,您需要使用ObservableCollection<T>关键字重置ObservableCollection<T>,但它们很少见。 这是一种特殊类型的集合,它在内部通知UI有关其内容的所有更改(如添加,删除等)。您需要的是在ViewModel的生命周期中使用new关键字设置一次,然后通过newAdd(T item)Remove(T item)方法等操作您的项目。 并且UI将收到有关它的通知并自动更新。