【问题标题】:DataGridComboBoxColumn does not display ObservableCollectionDataGridComboBoxColumn 不显示 ObservableCollection
【发布时间】:2014-11-22 23:30:22
【问题描述】:

示例代码:

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

【问题讨论】:

    标签: c# .net wpf xaml mvvm


    【解决方案1】:

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

    【讨论】:

    • 但是加载输入的上下文(目前)不在数据网格上下文中,只有选定的值应该是......并且示例给我的解决方案并不能解决我的问题......还有其他方法吗?
    • 我相信我之前的评论仍然有效 - 您不能期望从 a-la ItemsSource="{Binding Genres}" 列直接绑定到 VM。在我更新的示例中,我使用静态资源来解决您的第一个问题。稍后,当您实现一组特定于项目的类型可能性时,您将不得不使用更像我在链接中包含的内容。
    猜你喜欢
    • 2013-04-24
    • 1970-01-01
    • 2012-01-23
    • 2019-11-27
    • 2013-03-30
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多