c# - WPF,对于 listView 中的 Properties.Settings (StringCollection) 的 OnPropertyChanged 不起作用
问题描述
我尝试从 Properties.Settings (StringCollection) 为 listView 设置内容。Contet 设置成功,但如果我删除项目,listView 不会刷新。如果我关闭并打开 SettingWindow,则 listView 中的内容是正确的。意思是,DataBinding 出了点问题,OnPropertyChanged 可能不起作用。
设置窗口.xaml:
<Window x:Class="FilmDbApp.Views.SettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:FilmDbApp.Properties"
xmlns:local="clr-namespace:FilmDbApp.Views"
mc:Ignorable="d"
Title="Setting" Height="500" Width="400" ResizeMode="NoResize" WindowStartupLocation="CenterOwner">
<DockPanel>
<TabControl>
<TabItem Header="Genre options">
<StackPanel>
<ListView ItemsSource="{Binding Source={x:Static p:Settings.Default}, Path=Genres, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedGenre}"" VerticalAlignment="Top"/>
<Button Command="{Binding DeleteGenreCommand}" CommandParameter="{Binding SelectedGenre}" Content="Delete"/>
</StackPanel>
</TabItem>
<TabItem Header="Autosave options"/>
</TabControl>
</DockPanel>
</Window>
设置窗口.cs:
using System.Windows;
using FilmDbApp.ViewModels;
namespace FilmDbApp.Views
{
/// <summary>
/// Interaction logic for SettingWindow.xaml
/// </summary>
public partial class SettingWindow : Window
{
public SettingWindow()
{
InitializeComponent();
DataContext = new SettingWindowViewModel();
}
}
}
设置WindowViewModel.cs:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using FilmDbApp.Views;
using FilmDbApp.Models;
using FilmDbApp.Utils;
namespace FilmDbApp.ViewModels
{
class SettingWindowViewModel : INotifyPropertyChanged
{
private string selectedGenre;
public string SelectedGenre
{
get { return selectedGenre; }
set
{
selectedGenre = value;
OnPropertyChanged("SelectedGenre");
}
}
public SettingWindowViewModel()
{
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
// Delete genre
private RelayCommand deleteGenreCommand;
public RelayCommand DeleteGenreCommand
{
get
{
return deleteGenreCommand ??
(deleteGenreCommand = new RelayCommand(obj =>
{
string genre = obj as string;
Properties.Settings.Default.Genres.Remove(genre);
Properties.Settings.Default.Save();
OnPropertyChanged("Genres");
}, (obj) => Properties.Settings.Default.Genres.Count > 0 && obj != null));
}
}
}
}
解决方案
您可以利用 ViewModel 的强大功能,而不是绑定到其他源中的其他属性,它用于在视图和模型之间工作。
将以下属性添加到 ViewModel
class SettingWindowViewModel : INotifyPropertyChanged
{
public List<Genre> Genres => Properties.Settings.Default.Genres;
...
}
并绑定到它
<ListView ItemsSource="{Binding Genres}"
SelectedItem="{Binding SelectedGenre}"... />
现在在各种命令中,您应该能够告诉绑定更新
OnPropertyChanged(nameof(Genres));
推荐阅读
- linux - 在 arm-v8 程序集的插入排序代码中找不到分段错误
- php - 如何在循环外调用数据?
- python - 用`pandas`解析csv文件时`with open(...)`有什么功能?
- sql - 无法识别语句中“DELETE”“FROM”“CTE”附近的输入
- python - 旋转由 numpy 数组处理的图像
- php - phpinfo() 显示与 php.ini 不同的值
- c# - 如何解决 masstransit.rabbitmq(5.3.2)、rabbitmq.client(5.1.0) 的大量发布消息的 541 问题
- javascript - 如何获取json数组?
- c# - Entity Framework Core - 有效地在数据库中存储/查询多语言记录
- docker - 使用 NGINX 的 SSL 代理通过 Docker 导致网关错误