wpf 向 List 添加新项目后 ListView 未更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28427296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:56:10  来源:igfitidea点击:

ListView not updated after adding new items to List

c#wpflistobservablecollectioninotifypropertychanged

提问by Dhinnesh Jeevan

I have a ListViewbounded to a List of a class I created. When doing an operating, it was supposed to add/remove items from the list, but my ListViewwasn't updated even though I used INotifyPropertyChanged.

我有一个ListView绑定到我创建的类的列表。在进行操作时,它应该从列表中添加/删除项目,但ListView即使我使用了INotifyPropertyChanged.

If I use ObservableCollection, it works but I need to have the list sorted, and ObservableCollectiondoesn't do sorting for WPF4.0 :(

如果我使用ObservableCollection,它可以工作,但我需要对列表进行排序,并且ObservableCollection不会对 WPF4.0 进行排序:(

Any way I can make the List binding work? Why didn't it work even though I used INotifyPropertyChanged?

有什么办法可以使 List 绑定工作?为什么即使我使用了它也不起作用INotifyPropertyChanged

XAML:

XAML:

<ListView BorderThickness="0" ItemsSource="{Binding SelectedValues, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Padding="5">
                    <ListView.View>
                        <GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
                            <GridViewColumn DisplayMemberBinding="{Binding Value}"></GridViewColumn>

VM:

虚拟机:

    private List<CheckBoxItem> _selectedValues = new List<CheckBoxItem>();

    public List<CheckBoxItem> SelectedValues
            {
                get { return _selectedValues; }
                set
                {
                    _selectedValues = value;
                    OnPropertyChanged();
                }
            }

    private void UnselectValueCommandExecute(CheckBoxItem value)
            {
                value.IsSelected = false;
                SelectedValues.Remove(value);
                //OnPropertyChanged("SelectedValues");
                OnPropertyChanged("IsAllFilteredValuesSelected");
            }

public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

The CheckBoxItemclass contains 2 properties, Valueand IsChecked, which I don't think is relevant here.

CheckBoxItem类包含2个属性,Value而且IsChecked,我不认为与此有关。

So basically, I have a button which uses the UnselectValueCommandExecuteto remove items from the list, and I should see the list updated in the UI, but I'm not.

所以基本上,我有一个按钮,它使用UnselectValueCommandExecute来从列表中删除项目,我应该看到 UI 中的列表已更新,但我没有。

When I debug, I can see the SelectedValueslist updated, but not my UI.

调试时,我可以看到SelectedValues列表已更新,但看不到我的 UI。

采纳答案by Francesco De Lisi

You need a CollectionViewSourcein your UI.

CollectionViewSource的用户界面中需要一个。

The XAML:

XAML

<Window x:Class="WavTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"        
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <CollectionViewSource Source="{Binding TestSource}" x:Key="cvs">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Order"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <ListView ItemsSource="{Binding Source={StaticResource cvs}}" DisplayMemberPath="Description"/>
</Window>

The code behind:

背后的代码

namespace WavTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var vm = new ViewModel();
            this.DataContext = vm;

            vm.TestSource.Add(new TestItem { Description="Zero", Order=0 });
        }
    }

    public class ViewModel 
    {
        public ObservableCollection<TestItem> TestSource { get; set; }

        public ViewModel()
        {
            TestSource = new ObservableCollection<TestItem>();
            TestSource.Add(new TestItem { Description = "Second", Order = 2 });
            TestSource.Add(new TestItem { Description = "Third", Order = 3 });
            TestSource.Add(new TestItem { Description = "First", Order = 1 });
        }
    }

    public class TestItem
    {
        public int Order { get; set; }
        public string Description { get; set; }
    }
}

Explanation:

说明

The ObservableCollectionraises the PropertyChangedevent as you expect, but you cannot sort it. So, you need the CollectionViewto sort it and bind the sorted collection to you ListView/ListBox. As you can see, adding an element after the DataContextinitialization affects the UI sorting the last added item ("Zero") correctly.

ObservableCollection提高了PropertyChanged像您期望的事件,但你不能排序。因此,您需要对其CollectionView进行排序并将排序后的集合绑定到您ListView/ ListBox。如您所见,在DataContext初始化后添加元素会影响 UI 对最后添加的项目(“零”)进行正确排序。

回答by user1

You need to use ObservableCollectionbecause this raises a collection changed event which your wpf ListView will pick up on.

您需要使用,ObservableCollection因为这会引发一个集合更改事件,您的 wpf ListView 将接收该事件。

How about doing

怎么办

Public ObservableCollection<object> MyList
{
   get 
   {
      return new ObservableCollection<object>(MySortedList);
   }
}

and then whenever you change your sorted list raise a property changed event for MyList.

然后每当您更改排序列表时,都会引发 MyList 的属性更改事件。

This obviously depends how you would like to sort your list as it might be possible to sort the ObservableCollectionyour question needs more info.

这显然取决于您希望如何对列表进行排序,因为可能对ObservableCollection您的问题需要更多信息进行排序。