2014-11-22 3 views
0

Пример кода:DataGridComboBoxColumn не отображается ObservableCollection

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> 

Проблема заключается в том, что я хочу выпадающий список, чтобы показать все возможные жанры добавлены к играм, динамически. Для этого я создал ObservableCollection в GameListViewModel. Это не работает! Я боролся с этим сейчас в течение 2 часов ... Позже я хочу, чтобы выбранное значение было Жанром в игре.

ответ

2

Ahhh, вы обнаружили источник многих разочарований разработчиков WPF - DataGrid не пересылает DataContext в столбцы. Вы не можете действительно полагаться на такие выражения, как ItemsSource = {Binding Genres} "в столбце, потому что структура не может его устранить. Это супер-раздражает.

Кроме того, вы не установили свой SelectedItemBinding - вот Рабочий пример:

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 код-за:

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)); 
    } 
} 

Вот некоторые полезные ссылки: это один должен чюо гк: http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

последнее решение, показанное здесь особенно актуальна: http://blogs.msdn.com/b/vinsibal/archive/2008/12/17/wpf-datagrid-dynamically-updating-datagridcomboboxcolumn.aspx

+0

Но контекст для загрузки ввода (пока) не в контексте DataGrid, только выбранное значение должно быть ... И решение, которое дает мне пример, не решает мою проблему ... Есть ли другой способ? – Ken

+0

Я считаю, что мой предыдущий комментарий все еще стоит - вы не можете ожидать привязки непосредственно к виртуальной машине из столбца a-la ItemsSource = "{Binding Genres}". В моем обновленном примере я использую статический ресурс, чтобы обойти вашу первую проблему. Позже, когда вы реализуете набор возможностей Genre для конкретных предметов, вам нужно будет использовать что-то более похожее на то, что я включил в ссылки. – Andrew

Смежные вопросы