WPF ListView在运行时不更新

时间:2017-12-30 09:30:11

标签: wpf listview data-binding

我有一个listview的itemsource绑定到一个Observable动物类集合。

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

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

预期行为:按钮点击应删除可观察集合中的第一项并更新用户界面

观察到的行为:按钮点击应删除可观察集合中的第一项但未更新用户界面

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();
            }
        }

1 个答案:

答案 0 :(得分:1)

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}"`

<小时/> 最好遵循MVVM方法并摆脱背后的代码:

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处理程序已删除