簡體   English   中英

為什么字符串INotifyPropertyChanged屬性更新而不是List <string> ?

[英]Why does a string INotifyPropertyChanged property update but not a List<string>?

在下面的WPF應用程序中,當您單擊該按鈕時,為什么TheTitle TextBlock會更新但FilesCopied ListBox不會更新?

XAML:

<Window x:Class="TestList3433.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <TextBlock Text="{Binding TheTitle}"/>
        <TextBlock Text="above"/>
        <ListBox ItemsSource="{Binding FilesCopied}"/>
        <TextBlock Text="below"/>

        <Button Content="Add to collection" Click="Button_Click"/>
    </StackPanel>
</Window>

后台代碼:

using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;

namespace TestList3433
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        #region ViewModelProperty: FilesCopied
        private List<string> _filesCopied = new List<string>();
        public List<string> FilesCopied
        {
            get
            {
                return _filesCopied;
            }

            set
            {
                _filesCopied = value;
                OnPropertyChanged("FilesCopied");
            }
        }
        #endregion

        #region ViewModelProperty: TheTitle
        private string _theTitle;
        public string TheTitle
        {
            get
            {
                return _theTitle;
            }

            set
            {
                _theTitle = value;
                OnPropertyChanged("TheTitle");
            }
        }
        #endregion

        public Window1()
        {
            InitializeComponent();
            DataContext = this;

            FilesCopied.Add("test1.txt");
            TheTitle = "This is the title";
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            FilesCopied.Add("test2.txt");
            TheTitle = "title was changed";
        }

        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}

回答:

謝謝Robert,我忘記了ObservableCollection。 這是答案:

將FilesCopied塊更改為:

#region ViewModelProperty: FilesCopied
private ObservableCollection<string> _filesCopied = new ObservableCollection<string>();
public ObservableCollection<string> FilesCopied
{
    get
    {
        return _filesCopied;
    }

    set
    {
        _filesCopied = value;
        OnPropertyChanged("FilesCopied");
    }
}
#endregion

並添加:

using System.Collections.ObjectModel;

您的更改處理程序位於列表的setter中; 但您沒有調用 setter(更改列表) - 您正在向現有列表添加項目。 有單獨的接口( IBindingList / IBindingListView等)用於處理列表通知。 BindingList<T>是具有通知支持的2.0列表的合理默認實現。

在.NET 3.0及更高版本中,另請參見INotifyCollectionChangedObservableCollection<T>

IMO:

    private readonly ObservableCollection<string> filesCopied =
            new ObservableCollection<string>();
    public ObservableCollection<string> FilesCopied {
        get { return filesCopied; }
    }

因為它沒有實現IBindingList(View),因此UI永遠不會知道你在列表中添加任何新內容。

使用BindingList或ObservableCollection。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM