在C#WPF中向ListView GridView添加项目

时间:2017-03-07 12:48:58

标签: c# wpf gridview listviewitem

您好,我在XAML中有这个Listview GridView

<ListView FontSize="10" Name="List_To_Lock" Grid.Row="3"  Background="DarkGray" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="4" Margin="4">
    <ListView.View>
        <GridView  >
            <GridView.Columns>
                <GridViewColumn  Header="No1" Width="40" DisplayMemberBinding="{Binding No1}"/>
                <GridViewColumn Header="No2" Width="150" DisplayMemberBinding="{Binding No2}"/>
                <GridViewColumn Header="No3" Width="280" DisplayMemberBinding="{Binding No3}"/>
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

我有这个班级

public class numbz
{
    public string No1 { get; set; }
    public string No2 { get; set; }
    public string no3 { get; set; }


}

并且在MainWindow类中我完成了这个

List<numbz> num = new List<numbz>();
private void AddToList(string path)
{
    string a1= "a1"+path;
    string b1= "b1"+path;
    string c1= "c1"+path;
    num.Add(new numbz() { No1 = a1, No2 = a2, No3 = a3 });
}

private void RfrshLstVw()
{
    List_To_Lock.ItemsSource = num;
}

 private void Add_Click(object sender, RoutedEventArgs e)
 {

    AddToList(textbox.text);
    RfrshLstVw();
 }

当我点击调用上面最新方法的添加按钮时,在listview上添加项目 但是当我更改文本框的内容并且listview中有一个项目时,它将不会添加下一个项目。 我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

当您再次将相同的集合分配给项目源时,WPF将不会刷新ListView。有不同的方法可以实现您想要的效果,但最好的方法是使用ObservableCollection<T>代替List<T>。在这种情况下,您甚至不需要刷新方法,因为只要向可观察集合中添加新项目,ListView就会自动更新。

答案 1 :(得分:2)

要扩展Pavel's answer,WPF正在侦听来自INotifyPropertyChanged(在持有列表的情况下)或来自INotifyCollectionChanged的事件(在这种情况下)列表本身)。

本着MVVM的精神,我使用了实现INotifyPropertyChanged接口的ViewModel,并将它们分配给View的DataContext属性,以便在例如ListView绑定到视图内的列表(即<ListView ItemsSource="{Binding ListProperty}"/>),然后WPF将看到ViewModel是INotifyPropertyChanged。然后,它会在财产发生变化时开始倾听。

但即便如此,WPF也不会接受列表中内的更改,只会更换列表本身时的更改。如果你想让它在列表中选择更改,那么你必须确保你绑定的属性在每次访问时返回一个不同的列表实例。

例如,通过使list属性在每次访问时生成一个新的IEnumerable:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private readonly List<string> _internalList;
    public IEnumerable ListProperty => _internalList.AsEnumerable();
    // Other code here, including code to raise the "PropertyChanged" event when you want WPF to refresh any bindings to the ListProperty
}

...然后当ViewModel触发PropertyChanged属性的ListProperty事件时,WPF将再次查看它,看到它是一个不同的引用,并将刷新自己新的IEnumerable。

但正如他所说,最好的方法是使用ObservableCollection。当你在列表中有大量项目时,这会更有效...然后WPF会选择更改而不必刷新整个列表。

ObservableCollection的工作方式是实现INotifyCollectionChanged接口。它会在列表中的任何内容发生更改时(例如,添加,移动,替换或移动某些内容时)引发事件。 WPF会看到该列表是INotifyCollectionChanged,并会自动开始侦听该事件。

该事件告诉WPF究竟发生了什么变化,这样就省去了重新加载整个列表的麻烦。