将新项目添加到列表后,ListView 未更新
ListView not updated after adding new items to List
我有一个 ListView
绑定到我创建的 class 列表。进行操作时,它应该从列表中 add/remove 项目,但我的 ListView
没有更新,即使我使用 INotifyPropertyChanged
.
如果我使用 ObservableCollection
,它可以工作,但我需要对列表进行排序,而 ObservableCollection
不会对 WPF4.0 进行排序:(
有什么方法可以使列表绑定工作?为什么我用了 INotifyPropertyChanged
还是不行?
XAML:
<ListView BorderThickness="0" ItemsSource="{Binding SelectedValues, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Padding="5">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn DisplayMemberBinding="{Binding Value}"></GridViewColumn>
虚拟机:
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));
}
CheckBoxItem
class 包含 2 个属性,Value
和 IsChecked
,我认为这与此处无关。
所以基本上,我有一个使用 UnselectValueCommandExecute
从列表中删除项目的按钮,我应该在 UI 中看到更新的列表,但我没有。
当我调试时,我可以看到 SelectedValues
列表已更新,但我的 UI 没有。
您需要使用 ObservableCollection
,因为这会引发一个集合更改事件,您的 wpf ListView 将在该事件上获取。
怎么样
Public ObservableCollection<object> MyList
{
get
{
return new ObservableCollection<object>(MySortedList);
}
}
然后每当您更改排序列表时,都会为 MyList 引发 属性 更改事件。
这显然取决于您希望如何对列表进行排序,因为它可能会排序ObservableCollection
您的问题需要更多信息。
您的 UI 中需要一个 CollectionViewSource
。
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>
后面的代码:
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; }
}
}
解释:
ObservableCollection
如您所料引发了 PropertyChanged
事件,但您无法对其进行排序。
因此,您需要 CollectionView
对其进行排序并将排序后的集合绑定到您 ListView
/ListBox
。
如您所见,在 DataContext
初始化后添加元素会影响 UI 正确排序最后添加的项目 ("Zero")。
我有一个 ListView
绑定到我创建的 class 列表。进行操作时,它应该从列表中 add/remove 项目,但我的 ListView
没有更新,即使我使用 INotifyPropertyChanged
.
如果我使用 ObservableCollection
,它可以工作,但我需要对列表进行排序,而 ObservableCollection
不会对 WPF4.0 进行排序:(
有什么方法可以使列表绑定工作?为什么我用了 INotifyPropertyChanged
还是不行?
XAML:
<ListView BorderThickness="0" ItemsSource="{Binding SelectedValues, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Padding="5">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn DisplayMemberBinding="{Binding Value}"></GridViewColumn>
虚拟机:
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));
}
CheckBoxItem
class 包含 2 个属性,Value
和 IsChecked
,我认为这与此处无关。
所以基本上,我有一个使用 UnselectValueCommandExecute
从列表中删除项目的按钮,我应该在 UI 中看到更新的列表,但我没有。
当我调试时,我可以看到 SelectedValues
列表已更新,但我的 UI 没有。
您需要使用 ObservableCollection
,因为这会引发一个集合更改事件,您的 wpf ListView 将在该事件上获取。
怎么样
Public ObservableCollection<object> MyList
{
get
{
return new ObservableCollection<object>(MySortedList);
}
}
然后每当您更改排序列表时,都会为 MyList 引发 属性 更改事件。
这显然取决于您希望如何对列表进行排序,因为它可能会排序ObservableCollection
您的问题需要更多信息。
您的 UI 中需要一个 CollectionViewSource
。
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>
后面的代码:
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; }
}
}
解释:
ObservableCollection
如您所料引发了 PropertyChanged
事件,但您无法对其进行排序。
因此,您需要 CollectionView
对其进行排序并将排序后的集合绑定到您 ListView
/ListBox
。
如您所见,在 DataContext
初始化后添加元素会影响 UI 正确排序最后添加的项目 ("Zero")。