【发布时间】:2020-11-09 10:49:10
【问题描述】:
我尝试从 Properties.Settings (StringCollection) 为 listView 设置内容。 Contet 设置成功,但如果我删除项目,listView 不会刷新。如果我关闭并打开 SettingWindow,则 listView 中的内容是正确的。意思是,DataBinding 出了点问题,可能 OnPropertyChanged 不起作用。
SettingWindow.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();
}
}
}
SettingWindowViewModel.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));
}
}
}
}
【问题讨论】:
-
如果您的意思是要删除列表中的一行,那么您需要拥有触发 CollectionChanged 事件而不是 PropertyChanged 的 ObservableCollection
-
你也可以使用 CollectionViewSource 的刷新功能吗?
-
不,您不能像这样更新绑定。您正在指定不同的来源。简单的解决方法是在
SettingWindowViewModel中创建 getter-only 属性,该属性将重定向到Properties.Settings.Genres并在绑定中使用它。然后你可以在命令中为它发出通知。 -
请注意,在 ItemsSource Binding 上设置
UpdateSourceTrigger=PropertyChanged是没有意义的。它仅在 TwoWay 或 OneWayToSource 绑定中有效。 -
@Sinatr,我必须在
SettingWindowViewModel中创建方法,这将是:1)从Properties.Settings.Genres获取项目到ObservableCollection2)将listView 与ObservableCollection连接并做一些事情3)转换ObservableCollection回Properties.Settings.Genres?
标签: c# wpf mvvm data-binding