Skip to main content
 首页 » 编程设计

c#之DataGridComboBoxColumn 不显示 ObservableCollection

2024年08月12日44linjiqin

示例代码:

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 个小时......后来我希望所选的值成为游戏中的流派。

请您参考如下方法:

啊哈,您已经发现了许多 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