Reputation: 776
I have a class like this.
public class ViewModel
{
public PengChat3ClientSock Sock { get; internal set; }
public ObservableCollection<Room> Rooms { get; internal set; }
public ViewModel(PengChat3ClientSock sock)
{
Sock = sock;
Rooms = new ObservableCollection<Room>();
}
}
and MainWindow.xaml.cs
public ObservableCollection<ViewModel> viewModel { get; set; }
(Of course it is initialized.)
And here is a constructor.
comboBox.ItemsSource = viewModel;
But here, i do not want to use viewModel
, only viewModel.Sock
.
How can i do this?
Upvotes: 0
Views: 1524
Reputation: 3234
You can only bind an ItemsSource to a type which implements IEnumerable. I have run into this before, and made a converter to convert any object to a list. It's a simple and reusable solution, which leaves the ViewModel logic separated from the view logic:
Converter:
public class ItemToCollectionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new List<object> { value };
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML
<UserControl.Resources>
<local:ItemToCollectionConverter x:Key="ItemToCollectionConverter"/>
</UserControl.Resources>
...
<ComboBox ItemsSource="{Binding Sock, Converter={StaticResource ItemToCollectionConverter}}"/>
Upvotes: 0
Reputation: 892
Usually you would go about this in a slightly different way:
Code:
<ComboBox ItemsSource="{Binding Sock}"/>
If you just want to set the ItemsSource from code-behind, which is kind of ugly, you might simply add the items in Sock to comboBox.Items - Alternatively you may need to create a new 'Binding' object from code-behind, but this is even uglier:
var binding = new Binding("Sock")
{
Source = viewModel
};
comboBox.ItemsSource = binding;
Please note that I haven't tested the 'Binding in code-behind approach', it's really an anti pattern to do it like that, especially if you're working with MVVM.
Also, you 'Sock' property is a class, and not a collection, so you won't really be able to do this; did you perhaps mean the 'Rooms' property of the ViewModel?
Upvotes: 0
Reputation: 2475
There is no viewModel.Sock, as viewModel is a collection of objects of type ViewModel, which contain that property.
Depending on your goals there are different solutions:
You can still bind comboBox to viewModel, but in the item template of the comboBox you can access the Sock property
You can create new collection that will contain only Sock objects ... but then you may have to make sure it is synchronized with the collection of ViewModel objects
Upvotes: 1