Temporarily switch off bindings in WPF - c#

The title of the question is bad, feel free to update it.
I have an observablecollection that generates a user control whenever it an item has been added to it.
However there are times where I just want to add to the collection and not have it create a usercontrol. Is there a way around this problem? Thanks.

Create a collection view around the observable collection and bind the UI to that. The collection view will have a filter so that only items you want in the UI are filtered in

Related

Reusing visual tree when moving items between two ItemControls

I have two ObservableCollections in my ViewModel. Both of same generic type.
Window has two ItemsControls each with ItemsSource bound on its own ObservableCollection from ViewModel.
Both use same same ItemTemplate. This ItemTemplate is very complex user control.
It's all done by the book.
In some cases, I move item from one collection to another. UI updates correctly. However, as control is complex, it needs about 1-2sec to render when it is recreated in new ItemsControl. And since this happens on drag and drop operation, it is not user friendly.
What I would like to do is to somehow preserve existing instance of ItemTemplate from source ItemsControl and reuse it in destination. I don't know if it is even possible, I couldn't find anything about it online.
I believe setup is fairly simple, but if needed I'll write some simplified version of code (I can't share the real code).
Thanks for any help.
What I would like to do is to somehow preserve existing instance of ItemTemplate from source ItemsControl and reuse it in destination. I don't know if it is even possible, I couldn't find anything about it online.
I am afraid it is not. When you disconnect an element from the visual tree and then add it back to a different parent element at a later stage, all elements that make up the control will be re-rendered.

Removing an item from a WPF binding listbox

I have a WPF application with a ListBox (called listMyItems) which is successfully bound to a class of MyItems that I created. I have a List of MyItems called currentMyItems which is then assigned as ItemSource to the ListBox. It all works fine, if I add an item to the currentMyItems it pops up on the list, etc.
The problem occurs when I try to remove the selected item in the ListBox. This is the code that I use:
currentMyItems.Remove((MyItem)listMyItems.SelectedItem);
The item disappears from the ListBox but the next time I update it, it pops back up as it was never deleted. Any tips?
I think you may be confused about how data binding works. When you bind a property, you are telling WPF to go look somewhere else for the value of that property.
When you bind the ListBox.ItemsSource property to currentMyItems, you are telling WPF to go look at the currentMyItems list to find its list of items. If currentMyItems is an ObservableCollection instead of a List<T>, then the UI will automatically receive a notification to update the bound value when you add or remove an item from the collection.
Based on what you say in the question, it sounds like you you have two collections, one of which is bound, and the other which is used to recreate the first collection anytime a change occurs. All that is not needed.
Just create one ObservableCollection<MyItem>, bind it to the ListBox.ItemsSource property, and then add or remove items from that single collection. It should work as you would expect.
<ListBox x:Name="listMyItems" ItemsSource="{Binding MyItems}" />
and
MyItems.Add((MyItem)listMyItems.SelectedItem)
MyItems.Remove((MyItem)listMyItems.SelectedItem)
If you're interested, I also have some beginner articles on my blog for WPF users who are struggling to understand the DataContext. You may want to check out Understanding the change in mindset when switching from WinForms to WPF and What is this “DataContext” you speak of?
If you bound it correctly to an ObservableCollection and currentMyItems is that collection. Than it means that you must have reloaded currentMyItems in meantime.
Also consider binding the SelectedItem property of your ListView - your view model doesn't have to know about the view at all.
Your source collection must be modufy (inherit from IList or ICollection). If your source collection does not support this method of your interface Remove, you can't remove item from source.
So, when you want to remove item you must cast ItemsSource to IList or ICollection:
var source = listbox.ItemsSource as IList ?? listbox.ItemsSource as ICollection;
and then check:
if (source == null) return;
then:
listbox.SelectedItems.ForEach(source.Remove);
listbox.Items.Refresh();
Make the currentMyItems<MyItem> an ObservableColection<MyItem>. This way it will raise a property change whenever modified and the UI gets updated accordingly.
By using ObservableCollection you will automatically get updates on the UI.
You should use an ObservableCollection instead of List.
A good thing is to always use ObservableCollection instead of List when something to do with UI

How to implement an actualisation once i've added items to my viewmodel's Observablecollection?

I am new to silverlight so bear with me.. i have a view model in which i have 3 ObservableCollections of 3 classes (inherited from INotificyPropertyChanged). One of this classes is "Favorites" . In a child pivot page(of the main panorama view), i modify the favorites (i add one to the database etc.).
How can i "update" the view of the main panorama view? is it sufficient to add the new favorite object to the ObservableCollection or do i need to implement some new actions? From what i understood, the views are active, so if i modify an element (even one linked though Binding) it should update. Is this true?
You don't need to do anything if you add or remove an item to an ObservableCollection, the UI will show this new item automatically. However, if you modify your underlying data object, the UI won't be updated unless your object have implemented INotifyPropertyChanged.
You can take a look at this post or this one.

How do I keep the selection in ListBox when reloading ItemsSource

I am experimenting with WPF and MVVM in our system. However iam having a problem with keeping things selected in lists using only MVVM ( without doing extra CollectionViews ).
What i currently have is the list
ObservableCollection<ReservationCustomerList> Customers;
And then a property storing the selected Customer
ReservationCustomerList SelectedCustomer;
In my opinion now, when the list reloads (actually from another thread async), the selection should be able to be kept, however this does not happen.
Does someone have a nice clean way of achieving this ?
The way we did it was that we did not replace the collection. We added/removed the entries and updated existing entries if required. This maintains the selection.
You can use LINQ methods like Except to identify items that are new or removed.
In case the reloaded list still contains the last selected item and you want that item to be selected, then you can raise the PropertyChange event for the property SelectedCustomer after your collection gets reloaded.
Please make your sure your viewmodel class implements INotifyPropertyChanged interface.
you can use the ICollectionView to select the entity you want.
ICollectionview view = (ICollectionView)CollectionViewSource.GetDefaultView(this.Customers);
view.MoveCurrentTo(SelectedCustomer);
in your Xaml the itemsControl must have IsSynchronizedWithCurrentItem=true
or if the ItemsControl has a SelectedItem property you can simply bind it to your SelectedCustomer Property.
When you "reload" your collection you basically replace all values in it with new values. Even those that look and feel identical are in fact new items. So how do you want to reference the same item in the list when it is gone? You could certainly use a hack where you determine the item that was selected by its properties and reselect it (i.e. do a LINQ search through the list and return the ID of the matching item, then reselect it). But that would certainly not be using best practices.
You should really only update your collection, that is remove invalid entried and add new entries. If you have a view connected to your collection all the sorting and selecting and whatnot will be done automagically behind the scenes again.
Edit:
var tmp = this.listBox1.SelectedValue;
this._customers.Clear();
this._customers.Add(item1); this._customers.Add(item2);
this._customers.Add(item3); this._customers.Add(item4);
this.listBox1.SelectedValue = tmp;
in the method that does the reset/clear works for me. I.e. that is the code I put into the event handling method called when pressing the refresh button in my sample app. That way you dont even need to keep references to the customer objects as long as you make sure that whatever your ID is is consistent. Other things I have tried, like overwriting the collections ´ClearItems()´ method and overwriting ´Equals()´ and ´GetHashCode()´ didn't work - as I expected.

Most efficient way to retrieve/update an object from a collection?

I'm working with a silverlight datagrid that is bound to an observable collection of a business object.
We do not support inline editing of the objects within the grid but we do display a corresponding editing panel for the user selected row.
When the user submits the edits from this panel, I'm persisting the changes in the DB but I'd like the changes to also reflect in the grid.
I know that through the use of the observable collection and notify property changed that if I change the object that the selected row is bound to, the changes will display in the grid.
However, since I'm not inline editing, I need to search the observable collection for the object and make the change to the business object's instance in the observable collection.
I'd like to avoid having to loop through the collection to find said object but I'm worried this is the only real way.
There's no other more efficient, less performance-heavy way that I'm not aware of to retrieve an object from a collection correct? Other than simply to loop through until I hit it?
can you bind your edit grid to the selected item of the display grid? Since they are references this will push/pull changes into the observable collection which can then be persisted.
after having some critical exceptions happen that i couldn't keep track of i decided to avoid the databinding to the edit panel and go with Jeffrey L Whitledge's suggestion.
i'm maintaining a reference to the object displayed in the panel and with the notify changed, when i the user submits the update panel and i persist the changes to the business objects, i'm setting the changes to the grid row object that's bound.
thx guys

Categories

Resources