首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在WPF DataGrid中绑定ComboBoxColumn的ItemsSource

在WPF DataGrid中绑定ComboBoxColumn的ItemsSource
EN

Stack Overflow用户
提问于 2011-03-24 01:28:45
回答 8查看 124.7K关注 0票数 86

我有两个简单的模型类和一个ViewModel...

代码语言:javascript
复制
public class GridItem
{
    public string Name { get; set; }
    public int CompanyID { get; set; }
}

public class CompanyItem
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class ViewModel
{
    public ViewModel()
    {
        GridItems = new ObservableCollection<GridItem>() {
            new GridItem() { Name = "Jim", CompanyID = 1 } };

        CompanyItems = new ObservableCollection<CompanyItem>() {
            new CompanyItem() { ID = 1, Name = "Company 1" },
            new CompanyItem() { ID = 2, Name = "Company 2" } };
    }

    public ObservableCollection<GridItem> GridItems { get; set; }
    public ObservableCollection<CompanyItem> CompanyItems { get; set; }
}

...and a simple Window:

代码语言:javascript
复制
<Window x:Class="DataGridComboBoxColumnApp.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>
        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GridItems}" >
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" />
                <DataGridComboBoxColumn ItemsSource="{Binding CompanyItems}"
                                    DisplayMemberPath="Name"
                                    SelectedValuePath="ID"
                                    SelectedValueBinding="{Binding CompanyID}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

在App.xaml.cs中将ViewModel设置为主窗口的DataContext

代码语言:javascript
复制
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        MainWindow window = new MainWindow();
        ViewModel viewModel = new ViewModel();

        window.DataContext = viewModel;
        window.Show();
    }
}

如您所见,我将DataGrid的ItemsSource设置为ViewModel的GridItems集合。此部件正常工作时,将显示名为"Jim“的单一网格线。

我还希望将每一行中ComboBox的ItemsSource设置为ViewModel的CompanyItems集合。此部分不起作用: ComboBox保持为空,并且在调试器输出窗口中我看到一条错误消息:

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。BindingExpression:Path=CompanyItems;DataItem=null;目标元素为'DataGridComboBoxColumn‘(HashCode=28633162);目标属性为'ItemsSource’(类型为'IEnumerable')

我相信WPF希望CompanyItemsGridItem的一个属性,但事实并非如此,这就是绑定失败的原因。

我已经尝试使用RelativeSourceAncestorType,如下所示:

代码语言:javascript
复制
<DataGridComboBoxColumn ItemsSource="{Binding CompanyItems, 
    RelativeSource={RelativeSource Mode=FindAncestor,
                                   AncestorType={x:Type Window}}}"
                        DisplayMemberPath="Name"
                        SelectedValuePath="ID"
                        SelectedValueBinding="{Binding CompanyID}" />

但这在调试器输出中给出了另一个错误:

System.Windows.Data错误:4:无法找到具有引用'RelativeSource FindAncestor,AncestorType='System.Windows.Window',AncestorLevel=‘1’的绑定源。BindingExpression:Path=CompanyItems;DataItem=null;目标元素为'DataGridComboBoxColumn‘(HashCode=1150788);目标属性为'ItemsSource’(类型为'IEnumerable')

问题:如何将DataGridComboBoxColumn的ItemsSource绑定到ViewModel的CompanyItems集合?这有可能吗?

提前感谢您的帮助!

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-03-24 02:37:24

请检查下面的DataGridComboBoxColumn xaml是否适用于您:

代码语言:javascript
复制
<DataGridComboBoxColumn 
    SelectedValueBinding="{Binding CompanyID}" 
    DisplayMemberPath="Name" 
    SelectedValuePath="ID">

    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

在这里,您可以找到针对您所面临问题的另一种解决方案:Using combo boxes with the WPF DataGrid

票数 129
EN

Stack Overflow用户

发布于 2011-03-24 04:22:32

documentation on MSDN about the ItemsSource of the DataGridComboBoxColumn表示只有静态资源、静态代码或组合框项目的内联集合才能绑定到ItemsSource

若要填充下拉列表,请首先使用以下选项之一设置ComboBox的ItemsSource属性:

  • 静态资源。有关更多信息,请参见静态标记扩展。
  • An x:Static code entity。有关更多信息,请参见x:静态标记扩展。
  • ComboBoxItem类型的内联集合。

如果我理解正确的话,绑定到DataContext的属性是不可能的。

事实上:当我在ViewModel中将CompanyItems设置为静态属性时……

代码语言:javascript
复制
public static ObservableCollection<CompanyItem> CompanyItems { get; set; }

..。将ViewModel所在的命名空间添加到窗口...

代码语言:javascript
复制
xmlns:vm="clr-namespace:DataGridComboBoxColumnApp"

..。并将绑定更改为...

代码语言:javascript
复制
<DataGridComboBoxColumn
    ItemsSource="{Binding Source={x:Static vm:ViewModel.CompanyItems}}" 
    DisplayMemberPath="Name"
    SelectedValuePath="ID"
    SelectedValueBinding="{Binding CompanyID}" />

..。然后它就起作用了。但是,将ItemsSource作为静态属性有时可能是可以的,但这并不总是我想要的。

票数 48
EN

Stack Overflow用户

发布于 2015-01-29 12:46:12

正确的解决方案似乎是:

代码语言:javascript
复制
<Window.Resources>
    <CollectionViewSource x:Key="ItemsCVS" Source="{Binding MyItems}" />
</Window.Resources>
<!-- ... -->
<DataGrid ItemsSource="{Binding MyRecords}">
    <DataGridComboBoxColumn Header="Column With Predefined Values"
                            ItemsSource="{Binding Source={StaticResource ItemsCVS}}"
                            SelectedValueBinding="{Binding MyItemId}"
                            SelectedValuePath="Id"
                            DisplayMemberPath="StatusCode" />
</DataGrid>

上面的布局对我来说工作得很好,应该也适用于其他人。这种设计选择也是有意义的,尽管在任何地方都没有得到很好的解释。但是,如果您的数据列包含预定义的值,则这些值在运行时通常不会更改。因此,创建一个CollectionViewSource并初始化数据一次是有意义的。它还摆脱了较长的绑定来查找祖先并绑定到它的数据上下文(我一直觉得这是错误的)。

我把这篇文章留给那些为这个绑定而苦苦挣扎的人,并想知道是否有更好的方法(因为这个页面显然还会出现在搜索结果中,这就是我来到这里的原因)。

票数 42
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5409259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档