将视图模型中的 ObservableCollection 绑定到列表框

Binding ObservableCollection in viewmodel to listbox

我对 MVVM 和绑定还很陌生,我正在尝试学习使用它。 我 运行 遇到了将我的视图模型绑定到视图的问题,特别是将可观察集合绑定到列表框。

这是我的视图模型的样子:

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>

您的视图模型中似乎有错字。

RaisePropertyChanged("_networkList1");

您想为 public 属性 而非私有变量发出 属性 更改通知。

RaisePropertyChanged("NetworkList1");

这可能会阻止您的视图正确更新。

除了 Gaurav 回答之外,如果 _networkList1 是您 NetworkViewModel class 中的私有字段,如何在 Networking 中访问它 window?我的意思是下面这行是什么意思?

lb1.ItemsSource = _networkList1;

当您定义 属性 (NetworkList1) 时,您必须 使用 它才能获得其功能的优势(例如让 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}">

有效,因为 NetworkList1NetworkViewModel 的 属性。

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