(WPF) Binding two classes to a control - wpf

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.

Related

Bind a SortedList to ListBox WPF

I'm converting an older .NET WinForms app to WPF. It uses a SortedList:
Dim MyCol as New System.Collections.SortedList(New CaseInsensitiveComparer)
It fills a ListBox in the form by iterating the list, i.e. no data binding.
For Each p In MyCol.Values
lstBox.Items.Add(p.Name, False)
Next
It's nice because the items appear in the list sorted. Also, because it contains Key,Value pairs, you can instantly get a desired object from the list, or see if it is in the list at all:
If MyCol.Contains("the key") ...
myObject = MyCol("the key")
Debug.Print(myObject.Name)
I do this a LOT in the app, so the 'random access' nature of the SortedList is very important for performance.
So, fast forward to WPF, I need to bind my ListBox to MyCol, but would like to keep it as a SortedList, if possible. How can I bind it?
Edit: To clarify further, I am trying to do it right and want to use MVVM. And ideally I'd bind an ObservableCollection(of myClass) to the ListBox, and use Linq to sort and to query for a particular item. But then I've lost the 'random access' that I had with the SortedList, and I fear this would be a significant performance hit. But I haven't been able to figure out how to convert the SortedList to an ObservableCollection (I'm good, but not super-advanced), so I posted this question to explore if it's possible to stick with the SortedList first, before abandoning it for something else.
What I ended up doing, at least for starters:
In my ViewModel, I have a dependency property of type System.Collections.ICollection. Let's call it MyColProperty.
Once MyCol is populated, I assign it to the property like this. (SortedList.Values is of type System.Collections.ICollection).
MyColProperty = MyCol.Values
In the XAML, the ListBox binds to it like this:
<ListBox ItemsSource="{Binding MyColProperty}" DisplayMemberPath="Name"></ListBox>
And that works to display the Name property of my objects in the MyCol SortedList. So it's sort-of MVVM, though it's not an observable collection. I'll have to see how far I can take it with that short-coming, and then make a decision whether to switch to a true ObservableCollection, or if this will do.
Thanks very much, and hope it helps someone who comes across it.
Sandra
one way would be to simply set the SortedList as ItemsSource for the WPF ListBox and use the Name Property as DisplayMemberPath.
lstBox.ItemsSource = MyCol;
lstBox.DisplayMemberPath = "Name";
nervertheless you should also look into MVVM and Binding when doing WPF now :)
Make your collection MyCol as a collection of key and value, maybe something like,
new List<tuple<string,string>>()
Then bind your listBox to this collection with DisplayMemberPath as Item2 and use Item one as your key for searching etc.
Also you can use LINQ to sort your list,
myCol.OrderBy(p => p.Item2)

WPF DataGrid Binding List of Object that contains Dictionary<string,string> in XAML

I'm trying to figure out how to display the data from a dictionary property of a list inside a WPF DataGrid GridViewColumn
All the examples I find only appear to map to list of simple entities that can be . traversed like {Binding Answers.Title}. Mine however would be more like {Binding Answers["Title"]} which doesn't work in XAML
I'm missing something obvious here. Any ideas?
Edit: The list contains an entity that contains a Dictionary. Where Answers is the dictionary in the entity.
If I understand you correctly, you have a dictionary as the DataContext, and you need to display either its key or value as ListBoxItem. You can try following :
Here Data is the dictionary you can change the DisplayMemberPath="Key", if you need to display key. This can also be used to display data from a property while a complex object is in DataContext.
I'd imagine you simply bind the item source to the dictionary.Values as you would any collection and then create a data template as usual for the item
I.e. mygridview.datacontext = mydictionary.values

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

WPF - Combobox SelectedItem not getting set?

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

autoupdate a list in wpf

I want to display a bunch of Objects i have created in a ListBox. My objects implement the INotifyPropertyChanged Interface.
I tried to use an ObservableCollection, which i have bound to a listbox Control (listbox1.DataContext = MyCollection)
But this does not exactly what i want to do, because the Listbox is not refreshed when one of the properties of one of my objects in MyCollection changes.
I have found this blogposting: http://sweux.com/blogs/psampaio/index.php/2009/04/13/creating-a-custom-observable-collection-in-wpf
is this realy the easyiest/only way to keep track of several objects?
I'm not sure, but have you tried using a datatemplate for your listbox items? like, a textbox that explicitly sets it's text to the appropriate binding.

Resources