wpf 如何获取 ItemsSource 以刷新其绑定?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/806714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get an ItemsSource to refresh its bind?
提问by Edward Tanguay
I've got a view which shows a listbox that is bound to GetAll():
我有一个视图显示绑定到GetAll()的列表框:
<DockPanel>
<ListBox ItemsSource="{Binding GetAll}"
ItemTemplate="{StaticResource allCustomersDataTemplate}"
Style="{StaticResource allCustomersListBox}">
</ListBox>
</DockPanel>
GetAll() is an ObservableCollection propertyin my ViewModel:
GetAll() 是我的 ViewModel 中的 ObservableCollection 属性:
public ObservableCollection<Customer> GetAll
{
get
{
return Customer.GetAll();
}
}
which in turn calls a GetAll() model methodwhich reads an XML file to fill the ObservableCollection.:
它依次调用 GetAll() 模型方法,该方法读取 XML 文件以填充 ObservableCollection。:
public static ObservableCollection<Customer> GetAll()
{
ObservableCollection<Customer> customers = new ObservableCollection<Customer>();
XDocument xmlDoc = XDocument.Load(Customer.GetXmlFilePathAndFileName());
var customerObjects = from customer in xmlDoc.Descendants("customer")
select new Customer
{
Id = (int)customer.Element("id"),
FirstName = customer.Element("firstName").Value,
LastName = customer.Element("lastName").Value,
Age = (int)customer.Element("age")
};
foreach (var customerObject in customerObjects)
{
Customer customer = new Customer();
customer.Id = customerObject.Id;
customer.FirstName = customerObject.FirstName;
customer.LastName = customerObject.LastName;
customer.Age = customerObject.Age;
customers.Add(customer);
}
return customers;
}
This all works fine EXCEPT when the user goes to another view, edits the XML fileand comes back to this view where the old data is still showing.
除了当用户转到另一个视图,编辑 XML 文件并返回到旧数据仍在显示的视图时,这一切都正常。
How can I tell this view to "refresh its bindings" so that it shows the actual data.
我怎么能告诉这个视图“刷新它的绑定”,以便它显示实际数据。
It feels like I am going about WPF here with too much of an HTML/HTTP metaphor, I sense there is a more natural way to get ObservableCollection to update itself, hence its name, but this is the only way I can get the user to be able to edit data in a WPF application at the moment. So help on any level is appreciated here.
感觉就像我在这里用太多的 HTML/HTTP 比喻来处理 WPF,我觉得有一种更自然的方法可以让 ObservableCollection 自我更新,因此它的名字,但这是我可以让用户使用的唯一方法目前能够在 WPF 应用程序中编辑数据。因此,这里感谢任何级别的帮助。
回答by Denis Troller
An ItemsControl
requests its binding once and caches the reference thereafter.
AnItemsControl
请求其绑定一次,然后缓存该引用。
If the content of the collection object are modified, and it implements INotifyCollectionChanged
(as ObservableCollection
does), it will pick up any added or removed object.
如果集合对象的内容被修改,并且它实现了INotifyCollectionChanged
(就像ObservableCollection
那样),它将选取任何添加或删除的对象。
Now, if you want the binding to supply a new collection object to the ListBox
, you can have your view-model implement INotifyPropertyChanged
and raise PropertyChanged
, passing in GetAll
as the property name.
This will have the effect of warning the binding that the property value has changed (there is a new ObservableCollection
ready to be picked up), which it will supply to the ListBox
, which will re-generate its items.
现在,如果您希望绑定为 提供一个新的集合对象ListBox
,您可以让您的视图模型实现INotifyPropertyChanged
和提升PropertyChanged
,并GetAll
作为属性名称传入。这将具有警告绑定属性值已更改的效果(有一个新的ObservableCollection
准备被拾取),它将提供给ListBox
,这将重新生成其项目。
So as long as you effect changes from your app, working on the ObservableCollection
returned by GetAll
, you can add and remove and the list will stay in synch. When you want to pick up external modifications (you might have a refresh button somewhere, or a natural point where it makes sense to reload the whole file), you can have your view-model raise the PropertyChanged
event, which will automatically call the property getter, which will call the static method, which will return a fresh new collection.
因此,只要您影响应用程序的更改,处理ObservableCollection
返回的 by GetAll
,您就可以添加和删除,列表将保持同步。当您想要获取外部修改时(您可能在某处有一个刷新按钮,或者可以重新加载整个文件的自然点),您可以让您的视图模型引发PropertyChanged
事件,该事件将自动调用属性 getter ,它将调用静态方法,该方法将返回一个全新的集合。
Nitpicker note: why do you give method names to properties?
Nitpicker 注意:为什么要为属性指定方法名称?
回答by user2267032
Below line work same as when we remove to add object in collection:
下面一行的工作与我们删除以在集合中添加对象时相同:
CollectionViewSource.GetDefaultView(CustomObservableCollection).Refresh();
回答by Joe White
Keep a reference to your ObservableCollection
and the XML file's last-modified time as of the time you loaded it. Whenever the window gets focus, check the timestamp on the disk file. If it's changed, clear and re-populate the ObservableCollection
. The GUI is automatically listening for change events from the ObservableCollection
and will re-populate automatically when you modify the collection's contents.
保留对您ObservableCollection
和 XML 文件在加载时的最后修改时间的引用。每当窗口获得焦点时,检查磁盘文件上的时间戳。如果已更改,请清除并重新填充ObservableCollection
. GUI 会自动侦听来自 的更改事件,ObservableCollection
并且会在您修改集合的内容时自动重新填充。