WPF ListView在运行时不更新

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF ListView在运行时不更新相关的知识,希望对你有一定的参考价值。

我有一个listview itemssource绑定到一个Observablecollection的Animal类。

当窗口加载时,listview会正确显示所有项目。

但我有一个按钮,从observablecollection中删除一个没有更新列表视图的项目。

预期行为:按钮单击应删除可观察集合中的第一个项目并更新UI

观察到的行为:按钮单击应删除可观察集合中的第一个项目,但不更新UI

public class Animal
{
    public int Num { get; set; }
    public string Name { get; set; }
}


 public class ViewModel:INotifyPropertyChanged
{
    private ObservableCollection<Animal> animals;

    public ObservableCollection<Animal> Animals
    {
        get { return animals; }
        set { animals = value; OnPropertyChanged("Animals"); }
    }

    public ViewModel()
    {
        Animals = new ObservableCollection<Animal>()
        {
            new Animal(){ Name="ASD", Num = 1},
            new Animal(){ Name="XYZ", Num = 2},
        };
    }
    public void Run()
    {
        Animals.RemoveAt(0);
    }
    public event PropertyChangedEventHandler PropertyChanged;
    // Create the OnPropertyChanged method to raise the event
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}



<Grid DataContext="{Binding Source={StaticResource ViewModelDataSource}}">
    <Button Content="Button" HorizontalAlignment="Left" Height="20" Margin="70,285,0,0" VerticalAlignment="Top" Width="100" Click="Button_Click"/>
    <ListView x:Name="mylistview" HorizontalAlignment="Left" Height="212" Margin="42,47,0,0" VerticalAlignment="Top" Width="446" ItemsSource="{Binding Animals}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Label Content="{Binding Num}"/>
                    <Label Content="{Binding Name}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</Grid>



public partial class MainWindow : Window
        {
            private ViewModel vm;
            public MainWindow()
            {
                InitializeComponent();
                vm = new ViewModel();
            }

            private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
            {
                vm.Run();
            }
        }
答案

ListView使用DataContext="{Binding Source={StaticResource ViewModelDataSource}}

在窗口中,您可以创建视图模型的另一个实例(vm = new ViewModel();)。之后,您有2个不同的实例和集合。 vm.Run();从集合中删除未连接到视图的项目。

您需要使用一个实例,因此请尝试查找视图中使用的相同资源:

public MainWindow()
{
    InitializeComponent();
    vm = (ViewModel)this.FindResource("ViewModelDataSource");
}

DataContext setter也可以简化:

`DataContext="{StaticResource ViewModelDataSource}"`


it is preferable to follow MVVM aproach and get rid of code behind:

1]在viewmodel中声明命令属性

public ICommand RunCmd { get; private set; }

2]使用一些现成的ICommand实现,例如, RelayCommand或DelegateCommand并从viewmodel构造函数初始化RunCmd属性:

RunCmd = new RelayCommand(Run);

3]将Button绑定到该命令:

<Button Content="Button" 
        HorizontalAlignment="Left" 
        Height="20" Width="100" Margin="70,285,0,0" 
        VerticalAlignment="Top" 
        Command="{Binding RunCmd}"/>

请注意,Click处理程序已被删除

以上是关于WPF ListView在运行时不更新的主要内容,如果未能解决你的问题,请参考以下文章

WPF - ListView 为空时不显示上下文菜单

在常规(支持)片段中使用 AsyncTaskLoader 更新适配器不更新 ListView

如何在另一个 Fragment 中更新 ListView?

从片段更新ListView适配器内的TextView

WPF:解决数据绑定时不更新数据的问题

ListView 未显示在片段中