c# - 编辑项目后刷新列表视图
问题描述
我有一个显示书籍列表的列表,但是在编辑了有关它的信息后,我无法在我的列表视图中获取更新的数据。我尝试使用 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));
}
解决方案
对不起,但我根本不理解你的代码......使用 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
推荐阅读
- javascript - Accessing object keys with for loop
- java - 无法从 Eclipse 市场安装 TestNG 出现以下错误:
- c# - 我对异步请求方案(asp-net-core)感到困惑
- javascript - 无法访问 Cloud Firestore 后端。后端在 10 秒内没有响应。(火库)
- asp.net - 如果连接两个库,那么调试就不行了?
- xml - How to filter from xml to get boot duration using powershell?
- android - React Native 启动进程 'command'npx 时出现问题
- time - 如何在 Azure Devops 中报告每个时间段的小时数?
- ruby-on-rails - 分配属性时,必须传递哈希作为参数,传递字符串
- flutter - 如何在图像圈内对齐图标