I am having a bit of trouble understanding the correct way to do the following:
The data I am binding to exists on the internet as a json file. On a timer tick, I download it and using a JavaScriptSerializer, I deserialize it into a class.
Now, I want to bind to that data but when I deserialize, it creates a new class, so my binding breaks (meaning I have to set the ItemsSource or DataContext again).
Does anyone know a way around this?
Thanks!
What is the control that you are trying to bind your data to? If you can bind an observable collection as your data source, all you need to do is to clear your observable collection before fetching the data, and just add the fetched record to the collection post deserialization.
If you do not use ObservableCollection, you can add public properties to your ViewModel and just refresh those when you get the data back. This will ensure the refresh happens becuase your view is bound to public properties of your view model and not aware of the object returned from the call.
After binding deserialized data you should call PropertyChange event of the property you want rebind. In case the selected value is in the new (deserialized) collection it should be reselected.
Related
I have a ViewModel with some ObservableCollection _questions, which is loaded from DB when VM instance created. Also this list is used to collect data to save back to DB.
This Vm is used for a View1 and it displays the list in ListView with filtering by a property using CollectionViewSource.GetDefaultView(_questions).Filter = ...
Now I need to create View2 which will display same list but without filtering.
I can't bind it to the same ObservableCollection _questions because it has filter defined on CollectionViewSource, but I need to use it to keep SaveToDb code same.
Is it possible to have different filtering on the same data source for two different ListViews?
I have never enjoyed using CollectionViewSource. I would instead filter using a new property in my ViewModel that filters using Linq:
public IEnumerable<MyType> FilteredItems()
{
get
{
return MyCollection.Where(x => x.MyProperty == SomeValue).ToArray;
}
}
I would then bind ItemsSource to this property and use INotifyPropertyChanged event to notify UI of changes to the collection.
Its hard to tell if this fits your scenario well as there is not much information provided on what you need to achieve.
I have a BindingSource which I use to bind to a grid. The binding source itself binds to a custom class. For instance
MyGrid.DataSource = MyBindingSource
'Bind the Binding source to data
For each classInstance as myClass in MyCollection
MyBindingSource.List.Add(classInstance)
Next
A user may add or delete items to/from this List. My aim is to save this updated List to the database. I need to determine if my binding source's list has changed (i.e. has items added to it, or has items removed from it).
I am aware that I could implement the INotifyPropertyChanged on my custom class, and exploit the OnPropertyChanged event, but my classes' property would never change in my case. The other solution that I can think of is to use the BindingSource's ListChanged event, and maintain a collection of all the added and the deleted rows there. Although this approach may work for me, I reckon its a bit flaky.
Does the binding source or a Collection (such as the IList in my case) provide any other properties that can help me determine the above?
When your view entity derives from NotificationObject and each property calls the "RaiseProperty" change in its setter, will all properties call "RaiseProperty" on object reassignment. Or do you have set each property manually when you want to notify WPF controls of property changes.
Ex.
Item/entity arrives from WCF.
Item that is already in an observable collection detects that the arrived item is already contained in the collection and should check for any properties that are different between item already in collection and item that arrived from WCF.
Can I do this?
EntityInCollection = EntityFromWCF and have each property raise its event? Or do I have to do this:
EntityInCollection.Property1 = EntityFromWCF.Property1... etc. for each property.
I have a gridview diplaying object and would like to animate the cells that get updated but I'm thinking that reassigning the reference will raise all events and not simply the ones that have changed/are different between the two objects.
Thanks
If you're replacing the entire object, the ObservableCollection will raise an event to notify of this change. UI components will (or should - I can't vouch for all controls, especially 3rd party ones) respond and refresh automatically.
I have an ItemsControl whose ItemsSource I assign (via code) an ObservableCollection (lets call it Items) of INotifyPropertyChanged objects (data model). This data model has a PointCollection property.
The view (XAML) binds to this PointCollection on a PolyLine (on the Points attribute).
Initially when i set this Items collection to the ItemsControl.ItemsSource, i can see that the lines are indeed rendered.
Issue:
When I set the ItemsControl.ItemsSource to something else (like another ObservableCollection which doesn't have any lines) THEN set it back to the original collection, I am unable to see the lines, even though the collection SHOULD render them because the collection data model's contain the PointCollection.
From what I was able to research, there is something particularly tricky about binding to a PointCollection. I was wondering if anybody has tackled this before and/or know of a way to get this to render (i.e. invalidate the control to somehow force a redraw)???
Thanks.
Alvin,
I have no idea if this will work but, have you tried creating a new PointCollection?:
PointCollection newCollection = new PointCollection( oldCollection );
myItemsControl.ItemsSource = newCollection;
If that doesn't work, maybe it may be necessary use a more WPF based syntax:
myItemsControl.SetValue( ItemsControl.PointsProperty, newCollection );
I am struggling with some PointCollection issues myself so if either of these options help, let me know.
I have a datagrid which has its ItemsSource bound to the result of a linq query (.ToList())
I can make changes to properties of the collection bound to the itemssource, and these changes are reflected immediately in the datagrid fields, such as;
myQueryList[2].myProperty = newValue
What I can't do though, is see the changes made in the database reflected in the datagrid by this;
myQueryList.Refresh(RefreshMode.OverwriteCurrentValues, myQueryList[2])
I have inspected the value of myQueryList[2].myProperty after this refresh, and it shows it has correctly updated from the database. Why does the datagrid not display it, and how can i get the datagrid to display it?
Also; I have found the same problem with using an ObservableCollection
Thanks to Casey's (edited) response in this post, i've found a workaround
I've implemented the SendPropertiesChanged() on the collection members and call it whenever i do a Refresh()
Once you convert a query (deffered/dynamic) to a collection (fixed) using ToList() method, a separate collection is created. This new collection has no connection to the query. When something changes in query, it does not reflect on collection. You will need to reset the ItemsSource property whenever you call Refresh() on query.