2014-11-22 62 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> 

的问题是,我想组合框来显示所有可能的流派加入到游戏动态。为此,我在GameListViewModel中创建了一个ObservableCollection。这是行不通的!我现在一直在挣扎2个小时......后来我想让选定的值成为游戏中的流派。

回答

2

啊,你已经发现了许多WPF开发人员的问题 - DataGrid不会将它的DataContext转发到列。你不能真的依赖像ItemsSource = {Binding Genres}“这样的语句,因为框架无法解决它,这太超级讨厌了。工作示例:

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

下面是一些有用的链接: 这一个应该禾RK: 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 2014-11-22 23:59:07

+0

我相信我之前的评论依然存在 - 你不能指望从列a-la ItemsSource =“{Binding Genres}”直接绑定到虚拟机。在我的更新示例中,我使用静态资源来解决第一个问题。后来,当你实现一个项目特定的体裁集合的可能性,你将不得不使用更像我包含在链接中的东西。 – Andrew 2014-11-23 00:44:25

相关问题