首页 > 解决方案 > 编辑项目后刷新列表视图

问题描述

我有一个显示书籍列表的列表,但是在编辑了有关它的信息后,我无法在我的列表视图中获取更新的数据。我尝试使用 listview.items.refresh()、ObservableCollection 和 INotifyPropertyChanged。如果我再次按下更新按钮并关闭弹出窗口,它将显示更新后的值

XAML:

                  <ListView x:Name="BooksView">
                    <ListView.ItemContainerStyle>
                        <Style TargetType="ListViewItem">
                            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_MouseLeftButtonDown" />
                        </Style>
                    </ListView.ItemContainerStyle>
                    <ListView.ItemTemplate >
                        <DataTemplate>
                            <Expander Background="#e8f1f5" Width="700">
                                <Expander.Header >
                                    <controls:BookControl Book="{Binding  Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Path=.}"/>
                                </Expander.Header>
                                <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" >

                                    <Button Content="Delete" Style="{StaticResource OptionsBtn}"  Background="#27496d" Click="ButtonDelete_OnClick"/>

                                    <Button Content="Update" Style="{StaticResource OptionsBtn}" Click="ButtonUpdate_OnClick" />

                                    <Button Content="More" Style="{StaticResource OptionsBtn}"  Background="#70416d"/>

                                    <Button Content="History" Style="{StaticResource OptionsBtn}" Background="#420000" />
                                </StackPanel>
                            </Expander>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

CS:

   public partial class AdminHome : Window
{
    private Client _client;
    private ObservableCollection<Book> _books;
    private readonly ServiceClient _serviceClient = new ServiceClient();

    public AdminHome(Client client)
    {
        this._client = client;
        InitializeComponent();
        _books = _serviceClient.BooksList();
        BooksView.ItemsSource = _books;
    }

    private void ButtonUpdate_OnClick(object sender, RoutedEventArgs e)
    {
        var selectedBook = BooksView.SelectedItem as Book;
        var updateBookPage = new UpdateBook(selectedBook);
        updateBookPage.Closed += UpdateBookPage_Closed;
        updateBookPage.Show();
        BooksView.Items.Refresh();

    }
}

模型 :

    public class Book : INotifyPropertyChanged
{
    public int ID { get; set; }
    public string Title { get; set; }
    public string UniqueCode { get; set; }
    public string Author { get; set; }

    private string editure;

    public string Editure
    {
        get => editure;
        set
        {
            if (editure == value) return;
            editure = value;
            OnPropertyChanged();
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

标签: c#wpfxaml

解决方案


对不起,但我根本不理解你的代码......使用 ObservableCollection 似乎是最好的方法:

你的班级可能是这样的(在我的例子中,我只是把 ID 和 Name 写得更短

public class Book() : INotifyPropertyChanged
{
    public void NotifyPropertyChanged(string propName)
    {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
    private long id=-1;
    public long ID { get { return this.id; } set { this.id = value; } }

    private string name="";
    public string Name 
    { 
        get 
        { 
            return this.name; 
        } 
        set 
        { 
            this.name = value;
            this.NotifyPropertyChanged("Name"); // When you edit a book's name, the update will be done automatically by binding.
        }
    }
}

那么你的 ViewModel 可能是这样的:

public void NotifyPropertyChanged(string nomPropriete)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(nomPropriete));
}
private Book selectedBook{get;set;}
public Book SelectedBook{get{return this.selectedBook;}set{this.selectedBook=value;}}

private List<Book> selectedBooks = new List<Book>();
public List<Book> SelectedBooks
{
   get { return selectedBooks; }
   set
   {
       selectedBooks = value;
   }
}
private ObservableCollection<Book> listBooks = new ObservableCollection<Book>();
public ObservableCollection<Book> ListBooks
{
   get { return listBooks; }
   set
   {
       listBooks = value;
       this.NotifyPropertyChanged("ListBooks"); //list will be updated when you add/remove items in it
   }
}

然后 XAML 将是这样的:

<ListView x:Name="ListViewBooks" SelectedItem="{Binding SelectedBook}"  ItemsSource="{Binding ListBooks}" SelectionChanged="ListBooks_SelectionChanged" >
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name"/>
            //Add as many columns as you want
        </GridView>
    </ListView.View>
</ListView>

在这里,您将列表视图绑定到“ListBooks”。每次您将修改列表(添加/删除元素,或编辑名称),lsit 将被更新而无需任何代码。

然后该功能ListBooks_SelectionChanged允许您更新 SelectedBooks 列表。所以当你想再做一个功能的时候,你只需要通过SelectedListBooks检查选择了哪些元素。

private void ListBooks_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    contexte.SelectedBooks = ListViewBook.SelectedItems.Cast<Book>().ToList();
}

别的,如果你在某个地方需要在同一个视图中显示一个新的书籍列表,永远不要做 ListBooks = new ObservableCollection(),你会失去你的绑定,并且什么都不会起作用(我花了一段时间才明白这一点)。当您需要这样做时,最好执行以下操作:

ListBooks.Clear();
foreach(Book book in newListToDisplay)
{
    ListBooks.Add(book);
}

我还建议您阅读有关 MVVM 的信息,这将对您的代码结构有所帮助。最后一件事,我发现您的代码中缺少一些东西:DataContext。您还需要定义数据上下文,例如“this.DataContext=this;” 如果你不使用 MVVM


推荐阅读