Reputation: 3328
Lets consider an animal Model
as following:
public class Animal
{
public string name { set; get; }
public int age { set; get; }
}
and a collection of Animal
object as following:
Dictionary<string, Dictionary<string, ObservableCollection<Animal>>> animals;
in my ViewModel
I populate animals
like:
var lions = new ObservableCollection<Animal>();
lions.Add(new Animal("myLion 1", 2));
var tigers = new ObservableCollection<Animal>();
tigers.Add(new Animal("myTiger 1", 1));
var wild = new Dictionary<string, ObservableCollection<Animal>>();
wild.Add("Lion", lions);
wild.Add("Tiger", tigers);
var cats = new ObservableCollection<Animal>();
cats.Add(new Animal("myCat 1", 2));
cats.Add(new Animal("myCat 2", 4));
var dogs = new ObservableCollection<Animal>();
dogs.Add(new Animal("myDog 1", 1));
var pets = new Dictionary<string, ObservableCollection<Animal>>();
pets.Add("cat", cats);
pets.Add("dog", dogs);
animals = new Dictionary<string, Dictionary<string, ObservableCollection<Animal>>>();
animals.Add("wild animals", wild);
animals.Add("pets", pets);
In the View
I define two ComboBox
es and one DataGrid
which are described as following:
"wild animals"
and "pets"
, and the SelectedItem
of combobox binds to selectedAnimalType
property of ViewModel
."cat"/"dog"
or "lion"/"tiger"
respectively for "pet"
or "wild animals"
. The SelectedItem
of this combobox is bound to selectedAnimalCategory
property of ViewModel
.DataGrid
displays animals based on the selected values of the two comboboxes.My DataGrid
is defined and bound as following:
<DataGrid>
<DataGrid.ItemsSource>
<MultiBinding Converter="{StaticResource animalSelectionConverter}">
<Binding Path="selectedAnimalType"/>
<Binding Path="selectedAnimalCategory"/>
</MultiBinding>
</DataGrid.ItemsSource>
<DataGrid.Columns>
<DataGridTextColumn Header="Animal Type" Binding="{Binding Path=XYZ}"/> <!--The Question-->
<DataGridTextColumn Header="Name" Binding="{Binding name}"/>
<DataGridTextColumn Header="Age" Binding="{Binding age}"/>
</DataGrid.Columns>
</DataGrid>
And finally, I define the AnimalSelectionConverter
as following:
public class AnimalSelectionConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ViewModel.Default.animals[(string)values[0]][(string)values[1]];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Question :
I'm binding Animal.name
and Animal.age
of selected collection of animals to columns of DataGrid
. However, I'm also interested to show the SelectedItem
of first combobox (i.e., selectedAnimalType
) on the DataGrid
. For example, I would like to see columns such as following on my DataGrid
:
| Animal Type | Name | Age |
---------------------------------------
| pets | myCat 1 | 2 |
| pets | myCat 2 | 4 |
pets
are passed by selectedAnimalType
to the converter, and converter uses this information plus selectedAnimalCategory
to get myCat 1
and myCat 2
. Therefore, would it be possible to return multiple values from the MultiValueConverter
so that I see my DataGrid
as aforementioned ?
Just in case anyone is interested to see a minimal possible running code example, I prepared a small project of my question and you can find the source-code here on DropBox.
Upvotes: 1
Views: 827
Reputation: 61369
The weirdness of that design aside...
No, you cannot
The signature of Convert
is:
Object Convert(
Object[] values,
Type targetType,
Object parameter,
CultureInfo culture
)
(MSDN)
So you have to return a single object. That object could even be a Tuple<string, object>
which would approximate multiple return values, but thats an even worse design.
If you want that data in your DataGrid
I would just name your combo-box and do an ElementName
binding:
<DataGridTextColumn Header="Animal Type"
Binding="{Binding ElementName=TypeComboBox, Path=SelectedItem}"/>
In a more general case, access the main data context by naming your root element "Root" and doing this:
<DataGridTextColumn Header="Animal Type"
Binding="{Binding ElementName=Root, Path=DataContext.SelectedType}"/>
Upvotes: 1