WPF - Combobox SelectedItem not getting set? - wpf

I have a ComboBox that has its ItemsSource bound to a static List<CustomSettings> of options. The ComboBox is part of a form which is bound to a CustomObject class, and one of the properties on that class is a CustomSettingProperty.
I would like to bind the SelectedItem of the ComboBox to the property specified in the CustomObject, however SelectedItem="{Binding Path=CustomSettingProperty}" is not setting the default selected item. Using breakpoints I can see that it is calling the get; method, so I think the problem might be in the fact the CustomSettingProperty is created separately from the List<CustomObject> so WPF does not think it is the same item.
Is there an easy way to do this? Or perhaps an alternative since the CustomSettings class does contain an Id?

If the item that is selected is not the same instance that is contained in the List, you must override Equals() in the CustomObject to let the ComboBox know that it is the same object.
If it's the same instance, maybe it's only a simple thing such as setting the BindingMode to TwoWay:
SelectedItem="{Binding Path=CustomSettingProperty,Mode=TwoWay}"

I found the solution, It was The Prism's Event Aggregator was passed with reference type so That the ui thread stops processing

Related

Updating an Observable Collection Based on a combobox selection

So I have an ObservableCollection of items called "Class1" and
Class1 has a property named "ID".
I use a datagrid from the WPFToolkit and bind to this collection.
Within the datagrid is a combobox column and I bind it's ItemsSource to the ID property of the class.
At this point, all is good and everything populates as it should. What I want to do is modify the ObservableCollection to reflect the value selected in the ComboBox.
I have a ValueConverter bound to the SelectedItemBinding on the ComboBox as follows:
SelectedItemBinding="{Binding Path=ID, Converter={StaticResource IDConverter}}
What is the best (i.e: WPF approved method) of modifying the collection? When the IDConverter ConvertBack() method is called, I get the appropriate Class1 instance, but I can't access the Observable collection from within the ValueConverter and I also don't have access to the SelectedIndex value from the Datagrid.
I could create a class as a static resource with a pointer to my collection and pass that as a ConverterParameter, but that seems sort of hokey and I'm assuming there must be some slicker way of doing this with databinding.
For the record, a simple solution is to create a local resource with a reference to the collection you wish to modify as a dependency property. You can then pass this as a ConverterParameter and have access to it in the ConvertBack() interface method.
A caveat: You will most likely encounter a DeferRefresh exception when you make changes to the collection and then you lose focus.
An excellent fix is found here:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/187b2b8f-d403-4bf3-97ad-7f93b4385cdf

Can I have a ValueConverter in my ViewModel?

I have a combobox bound to a collection, so the user can select one of the items. So far, so good.
The content of the combo box is driven by the item, but also by a value in my viewmodel. Imagine the value in my viewmodel is the language, I have dictionary of descriptions by language in my bound item, and I want to display the correct one.
How should I go about this?
This is a classic example of why the ViewModel exists - you want to have logic which depends on trivial state in the view, as well as the main model.
Imagine you are writing a unit test to run against the ViewModel for this behaviour. You would need the ViewModel to have a property mapped to the selected item. The ViewModel would also have another property which varies according to this selected item as well as the other value in the ViewModel you mentioned.
I think of this as the test-driven approach to ViewModel design - if you can't write a unit test to evaluate it then you haven't got the mix of state and published interfaces right.
So, yes, the ViewModel can solve the problem and if you push all the state down into it you can do the unification within the ViewModel.
Make an observable collection in your viewmodel of type Item. Bind the itemsource of your viewmodel to this observable collection.
public class Item
{
public String description {get;set;}
public String language {get;set;}
public override ToString()
{
return description;
}
}
Selected item would also be bound to a property of type Item as well.
The override of ToString displays the description.
The Selected item propery will have a reference to the selected object property where you can get the language from.

WPF: Binding DataGrid to a list<Product> having a DataGridComboBoxColumn bound to a list<Category>?

I have a DataGrid with ItemsSource set to a list of products and
I have a DataGridComboBoxColumn inside the DataGrid with ItemsSource set to a list of categories. That way I want the user to choose a certain category for each product.
I always get the binding error:
BindingExpression path error: 'Categories' property not found on 'object' ''Product' (Hash)
Well I do not want to make the Category list part of the Product entity as 1:N relation, although it would work that way.
I want to keep them separate.
Anyone knows a workaround?
Create class with static property like
static class ValueLists
{
public static IEnumerable<Category> Categories {get {... }}
}
and use following binding
ItemsSource="{x:Static myNs:ValueList.Categories}" />
this is kind of late reply but in order to share the knowledge I found this:
Binding a WPF DataGridComboBoxColumn with MVVM
This answer shows that is not always mandatory to convert the second list to a static class, you can always specify a RelativeSource and search for an specific Ancestor and then bind to the "other" list you have in your ViewModel.
This is probably relevant to your problem.
What is happening here?
The Columns collection is just a property in the Datagrid; this collection is not in the logical (or visual) tree, therefore the DataContext is not being inherited, which leads to there being nothing to bind to.

MVVM Update binding issue

I have user control to which I bind a viewmodel, this implements the INotifyPropertyChanged, thru the datacontext, this has a property that is a IList that I bind to the itemsdatasource of a grid, then on the code, in another class I add some values to the list, but the UI doesn't reflect this change although in debug I can see that the datagrid has this items added but they don't appear in the UI, can anybody help me, I can't see what is the problem.
ObservableCollection<T> is your friend. It implements INotifyCollectionChanged, saving you the trouble.

(WPF) Binding two classes to a control

I have two viewmodels. One which displays a collection of IPAddresses, and one which displays a collection of objects that has numerous parameters. One of these parameters is an IPAddress. So, I have another panel that binds to the properties of the second object. I would like a combobox to have the ItemSource set to the first object, but the selected item bound to the second object. However, I can only seem to set one datacontext on a control in code behind. Is there any way around this? I would prefer to do this all in code behind if possible (i find the xaml programming to be non-ideal at best), but I'll take anything.
For the ComboBox bind the collection of IPAddresses to the ItemsSource property, and bind the SelectedItem of the ComboBox to the IPAddress property of the SelectedItem of the collection of "numerous property objects".
This would be easier to answer if I had a better description of your objects including names. But it sounds to me like you should make a dictionary with the ipaddress as the key and the second object as the value.
If you can do that then you can bind to it in code like so:
comboBox.ItemsSource = dictionary;
comboBox.DisplayMemberPath = "Key";
comboBox.SelectedValuePath = "Value";
This is assuming that you have exactly one "second object" for every IPAddress in the collection. Which sounds about right given your description.
Take a look at the Source property of Bindings. It is basically a DataContext for a specific binding. It should make what you're trying to do very simple, especially in code behind.

Resources