Silverlight Combobox data binding : Basic and quick way? - silverlight

Please tell me the basic and quick way to bind a Collection(List,etc) to a combobox and handle the selection changed event and get the selected item.

This is quite easy. You can do this with XAML+Code or just code. I won't type out a complete solution as I feel you'll benefit more from completing that part yourself. I've assumed here that you already have some XAML declaring a combo box, so I've just shown some code (in C# as you didn't state what language you were using), just know that the event handler could easily be assigned via XAML instead.
this.combo.SelectionChanged +=
new SelectionChangedEventHandler(comboProjects_SelectionChanged);
this.combo.ItemsSource = myCollectionOfItems;
This sets up an event handler for the selection changing and also binds the combo to a collection, which it uses to source its items (hence the name, ItemsSource).
Then, in the SelectionChanged event handler, you can get the SelectedItem property to find out what is selected.
Note that there are some caveats with binding in the ComboBox, so you may find these links useful:
http://silverlight.net/forums/t/63616.aspx
http://silverlight.net/forums/p/87111/202335.aspx#202335

Related

how to bind button is enable property to a enum in wpf

i am using listView grouping based on an enum which {Updated and not Updated}. In my case, their is a button to call update I just want to disable if rows are in an updated group. See in the images.
The list that is present in updated section I want that the button should be disabled. I am using an example found in Here
IsEnabled={Binding ProperyNameOnYourViewModel, Mode=OneWay}
That will work assuming 1) your VM implements INotifyPropertyChanged and triggers appropriate event at the appropriate moment (typically, property's setter is responsible for that); 2) your control itself knows how to react on IsEnabled=false visually, i.e. changes color or whatever you like it to do.
Since you got an enum rather than bool, the easiest way to stick to the solution I've suggest is by extending your VM with yet another property, which recomputes boolean flag all the time. Then you might invoke PropertyChanged event not from your bool property (to which IsEnabled is actually bound), but from the enum property such that whenever it changes, WPF gets notified that boolean property has changed as well.
Otherwise, solve the problem with help of converters, which requires a lot more code.

Event that gets called when the control finished binding

I have an ItemsControl control. In its items I show a lot of things: images, textblocks, etc.
I have a 'Search' functionality implemented on the itemscontrol - meaning that if the user enters some letters from the keyboard, the items control will be refreshed. My Search method is in code-behind and it takes less than a second. However, the time between I enter the letters and see the results is 3-4 seconds. I have a window closing command and I want to put it in the exact moment before showing the search results. If I put this command in the end of my Search method (in the code-behind), there is still a few seconds delay between closing the window and showing the items. I'm thinking that the binding is slow and that's why i need to catch the event that gets called when the binding finishes. Is there such an event in WPF?
OnPropertyChanged event gets called before the Search methods finishes, so that doesn't help me.
I also tried with the OnDataContextChanged event, but it gets called just once - when the control is initialized. I need it to also get called when the user enters letters and new binding occurs.
When you establish a data binding between a source property and a target dependency property in WPF, this Binding is actually translated into a BindingExpression object which does the heavy lifting of updating the source and the target at the appropriate moments.
Unfortunately, BindingExpression does not provide events when something is updated, as you can see here: http://msdn.microsoft.com/en-us/library/system.windows.data.bindingexpression(v=vs.110).aspx
The only way is to set the UpdateSourceTrigger to Explicit when you define your binding, get the binding expression in code behind and update the source and target manually - then you have full control and can encapsulate your common functionality in this scenario.
You can obtain the BindingExpression by using the BindingOperations.GetBindingExpression static method: http://msdn.microsoft.com/en-us/library/system.windows.data.bindingoperations.getbindingexpression(v=vs.110).aspx
If you have any further questions, please feel free to ask.
P.S.: isn't there maybe another way to do this? If you're using a source collection that you bind to your ItemsControl, couldn't you perform the searching / filtering operations on the source collection and just let the collection binding update your ItemsControl?

WPF: How to trigger GUI behaviours in response to view-model events?

I'm developing a WPF/MVVM application and I have a listbox binding to data in a ViewModel. At various points I need the view model to cause the listbox to scroll to a given element.
How can I do this without creating a custom control and while still maintaining good separation of concerns?
I've currently got it working by creating a custom behavior class in the view layer with a dependency property VisibleIndex which the XAML code then binds to an integer in the view model:
<ListBox x:Name="myListBox"
local:ListBoxVisibilityBehavior.VisibleIndex="{Binding VisibleIndex}">
When the integer is set it triggers the dependency properties update handler which tells the listbox to scroll to the associated index.
This seems a bit hacky though because the dependency property value is never changed by the listbox and the update handler only gets called when the value changes, so the only way to ensure that the relevent item is visible is to do something like this:
// view-model code
this.VisibleIndex = -1;
this.VisibleIndex = 10;
The only reason I'm using a behaviour class at the moment is for binding my custom dependency property, is there a way to do something like this with events instead?
Attached properties are somewhat required in your case - as at some point, 'somewhere' you need to call the following method...
ListBox.ScrollIntoView(item)
or
ListBoxItem.BringIntoView();
And for that you need some sort of code behind - and attached properties/behaviors are a nice way of packaging that, w/o impacting your MVVM.
Having said that - if you just need to have your 'selected item' scrolled into view at all times (which is the case most of the time). Then you could use a different attached-property based solution (that again):
mvvm how to make a list view auto scroll to a new Item in a list view
All you have to do then is to set or bind to SelectedItem.
That's a bit 'nicer' if you wish - but the mechanism is the same.
For anyone else interested in the answer to this one of the MS engineers on the WPF forum cleared it up for me. Instead of binding to an event directly you bind to a wrapper object that encapsulates that event. The behaviour can then grab the reference to the wrapper from its DP and do whatever it wants with it i.e. subscribe to the event, trigger it etc.

WPF Binding to IDictionary<int,MyType>.Values Doesn't Respond to Property Changes?

I am binding a ListView a property that essentially wraps the Values collection (ICollection) on a generic dictionary.
When the values in the dictionary change, I call OnNotifyPropertyChanged(property). I don't see the updates on the screen, with no binding errors.
When I change the property getter to return the Linq extension dictionary.Values.ToList(), without changing the signature of the property (ICollection) it works with no problem.
Any reason why the Values collection bind and notify properly without projecting to an IList<>?
Calling OnNotifyPropertyChanged() isn't exactly correct in this case, since the collection is still the same, however the items in the collection have changed. I don't know exactly how the WPF binding code works, but it might do a quick check to see if the reference it is binding to has changed, and if not it won't update the UI.
The reason that ToList() works is because each time it is called, a new instance of List<T> is returned, so when OnNotifyPropertyChanged() is fired, WPF picks up on the change and updates all of its bindings.
I don't know if this is possible or not, but the ideal solution would be to use a collection for bindings that implements INotifyCollectionChanged. This will fire events that WPF monitors so that items can be added, removed, etc. from the UI as appropriate.

.NET WinForm ListBox item displays old value untill reassigned to itself

I populate a ListBox control with my own objects redefining ToString(). The objects are displayed correctly when I just add those objects using listBox1.Add(myObject). However, if I later change something in this object, no changes are displayed in the listbox. Debugging reveals that an object inside listBox1.Items is indeed changed, but it is not reflected on a screen.
Interestingly enough, if I reassign a particular listbox item to itself (sounds a bit weird, doesn't it?), like:
listBox1.Items[0] = listBox1.Items[0]
this line will display a correct value on screen.
What is going on here? Does it have anything to do with threading?
Since you're using ToString of the object to provide the text of the list box item, the ListBox has no idea that the value has changed. What you should do instead is have the object implement INotifyPropertyChanged then expose a public property such as Name or Text and return what you normally would have returned from ToString().
Then set the DisplayMember of the ListBox to the name of the new property.
Make sure you are correctly raising the PropertyChanged event in the object and the ListBox should be able to automatically pick up the changes.
Edit: Adrian's edit reminded me that I do believe you'll need to use a BindingList as your data source in order for the property change notifications to be picked up. A quick scan in Reflector looks like ListBox on its own will not pick up the property changes mentioned above. But INotifyPropertyChanged + BindingList should.
The ToString() value of each item is cached when the listbox is first displayed. If an item in the listbox's Items collection then changes, the listbox does not notice and still uses the cached ToString() values for display. To force the listbox to update, either call RefreshItems() to refresh all items, or call RefreshItem(int) specifying the index of the item to refresh.
From the MSDN docs for RefreshItems():
Refreshes all ListBox items and retrieves new strings for them.
EDIT: It turns out that both of these methods are protected, so cannot be called externally. In trying to find a solution, I came across this SO question that this question is basically a duplicate of.
Have you tried calling Refresh() on the ListBox? I think the problem is that the ListBox does not know your object changed. The reason reassigning the the item works is because the ListBox will repaint itself when the collection changes.
you could invalidate the control, forcing a re-paint... perhaps..

Resources