这是我的代码:
型号:
public class Person
{
public string FirstName { get; set; }
}
ViewModelBase:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
视图模型:
public sealed class PeopleViewModel : ViewModelBase
{
private ICollectionView _collectionView;
public ICollectionView View => _collectionView;
private ObservableCollection<Person> _personCollection;
public ObservableCollection<Person> PersonCollection
{
get { return _personCollection; }
set
{
if (value != this._personCollection)
_personCollection = value;
OnPropertyChanged("PersonCollection");
}
}
private string _filterSearchText;
public PeopleViewModel()
{
_personCollection = new ObservableCollection<Person>();
_collectionView = CollectionViewSource.GetDefaultView(PersonCollection);
Add(new Person() {FirstName="Homer"});
Add(new Person() {FirstName="Bart"});
Add(new Person() {FirstName="Lisa"});
}
public void Add(Person person)
{
PersonCollection.Insert(0, person);
}
public string FilterSearchText
{
get { return _filterSearchText; }
set
{
_filterSearchText = value;
OnPropertyChanged("FilterSearchText");
if (string.IsNullOrEmpty(value))
{
_collectionView.Filter = null;
}
else
{
_collectionView.Filter = x =>
((Person)x).FirstName.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
}
}
}
}
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private readonly PeopleViewModel _peopleViewModel = new PeopleViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = _peopleViewModel;
}
private void MyUpdateLogic()
{
var person = new Person() {FirstName="Marge"}
_peopleViewModel.Add(person);
}
...
}
MainWindow.xaml
<Grid>
<Grid DataContext="{Binding Source={StaticResource PeopleViewModel}}">
<Grid.RowDefinitions>
<RowDefinition MinHeight="243" />
</Grid.RowDefinitions>
<ListView x:Name="personListView"
ItemsSource="{Binding PersonCollection}"
Grid.Row="0"
Margin="0,0,0,5" >
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource CustomHeaderStyle}">
<GridViewColumn Width="Auto" DisplayMemberBinding="{Binding FirstName}"/>
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Height" Value="20" />
<EventSetter Event="MouseDoubleClick"
Handler="MyUpdateLogic" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
<TextBox x:Name="searchTextBox"
Text="{Binding FilterSearchText, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap"
MaxHeight="25"
MinHeight="25"
Height="25"
Grid.Row="1"
VerticalAlignment="Bottom" />
</Grid>
</Grid>
它在UI(Homer,Bart,Lisa)上显示初始列表的最有趣的部分,甚至过滤效果很好,当我更新searchTextBox
时,它更新UI并仅显示列表视图中的相应元素。但是当我添加新元素时,它并没有更新UI,即使它确实为可观察集合PersonCollection
添加了新元素。
我在这里缺少什么?如果我错误地实现了MVVM模式,也请告诉我。
更新
我还尝试绑定到ICollectionView:<ListView x:Name="personListView" ItemsSource="{Binding View}"
,它没有用。
尝试订阅PeopleViewModel
构造函数中的Refresh:
_personCollection.OnChange += _collectionView.Refresh();
在向列表中添加新元素后立即添加刷新:
public void Add(Person person)
{
PersonCollection.Insert(0, person);
_collectionView.Refresh();
}
它也没有用。
答案 0 :(得分:3)
您将Grid
的datacontext设置两次,只需删除此绑定
DataContext="{Binding Source={StaticResource PeopleViewModel}}"
在MainWindow构造函数中添加此行,
this.DataContext = _peopleViewModel;
您将整个DataContext设置为绑定到此实例,您应该知道Datacontext是否从父控件继承,如果您没有覆盖它。