Reputation: 3096
Sample code:
class GameListViewModel {
private IGameRepository repository;
public GameViewModel GameViewModel { get; set; }
public ObservableCollection<GameViewModel> Games { get; set; }
public ObservableCollection<GenreViewModel> Genres { get; set; }
public ICommand AddGame_ { get; set; }
public GameListViewModel() {
repository = new DummyGameRepository();
GameViewModel = new GameViewModel();
Games = new ObservableCollection<GameViewModel>(repository.GameList().Select(game => new GameViewModel(game)));
Genres = new ObservableCollection<GenreViewModel>(repository.GameList().Select(game => game.Genre).Distinct().Select(genre => new GenreViewModel(genre)));
AddGame_ = new RelayCommand(AddGame, CanAddGame);
}
}
class Game {
public string Title { get; set; }
public string SubTitle { get; set; }
public int Pegi { get; set; }
public Genre Genre { get; set; }
}
XAML:
<DataGrid ItemsSource="{Binding Games}" AutoGenerateColumns="False" Margin="0,32">
<DataGrid.Columns>
<DataGridTextColumn Header="Title" Binding="{Binding Title}" />
<DataGridTextColumn Header="Sub-Title" Binding="{Binding SubTitle}" />
<DataGridTextColumn Header="Pegi" Binding="{Binding Pegi}" />
<DataGridTextColumn Header="Genre" Binding="{Binding Genre.Name}" />
<DataGridComboBoxColumn Header="Test" ItemsSource="{Binding Genres}" DisplayMemberPath="Name" />
</DataGrid.Columns>
</DataGrid>
The problem is, I want the combobox to show all the possible genres added to games, dynamically. For that I have created a ObservableCollection within GameListViewModel. It does not work! I have been struggling with this now for 2 hours... Later I want the selected value to be the Genre within the Game.
Upvotes: 1
Views: 1718
Reputation: 1492
Ahhh, you have discovered the source of many WPF developer's fustrations - the DataGrid does not forward it's DataContext to the columns. You can't really rely on statements like ItemsSource={Binding Genres}" in the column, because the framework can't resolve it. It's super-annoying.
Also, you have not set your SelectedItemBinding - here is a working example:
xaml:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<CollectionViewSource Source="{Binding Possibilities}" x:Key="possibilities"/>
</Grid.Resources>
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" x:Name="dataGrid">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="test"
SelectedItemBinding="{Binding Selection}"
ItemsSource="{Binding Source={StaticResource possibilities} }">
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
cs code-behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel()
{
Items = new ObservableCollection<Item>()
{
new Item(){
Selection ="A"
}
}
};
}
}
public class Item : ViewModelBase
{
private string _selection = null;
public string Selection
{
get { return _selection; }
set { _selection = value; OnPropertyChanged("Selection"); }
}
}
public class ViewModel : ViewModelBase
{
private ObservableCollection<Item> _items = new ObservableCollection<Item>();
public ObservableCollection<Item> Items
{
get { return _items; }
set { _items = value; OnPropertyChanged("Items"); }
}
private ObservableCollection<string> _possibilities = new ObservableCollection<string>()
{
"A", "B", "C"
};
public ObservableCollection<string> Possibilities
{
get
{
return _possibilities;
}
set
{
_possibilities = value;
OnPropertyChanged("Possibilites");
}
}
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var propChanged = PropertyChanged;
if (propChanged != null)
propChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Here are some helpful links: this one should work: http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx
the last solution shown here is particularly relevant: http://blogs.msdn.com/b/vinsibal/archive/2008/12/17/wpf-datagrid-dynamically-updating-datagridcomboboxcolumn.aspx
Upvotes: 6