在WPF数据网格中绑定ComboBoxColumn的ItemsSource

时间:2022-07-10 17:01:26

I have two simple Model classes and a ViewModel...

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

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:

…和一个简单的窗口:

<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>

The ViewModel is set to the MainWindow's DataContext in App.xaml.cs:

ViewModel设置为app .xam .cs中的主窗口的DataContext:

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

As you can see I set the ItemsSource of the DataGrid to the GridItems collection of the ViewModel. This part works, the single Grid line with Name "Jim" is displayed.

如您所见,我将DataGrid的ItemsSource设置为ViewModel的GridItems集合。此部分工作,显示名为“Jim”的单个网格线。

I also want to set the ItemsSource of the ComboBox in every row to the CompanyItems collection of the ViewModel. This part does not work: The ComboBox remains empty and in the Debugger Output Window I see an error message:

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

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=CompanyItems; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=28633162); target property is 'ItemsSource' (type 'IEnumerable')

System.Windows。数据错误:2:无法找到目标元素的管理框架元素或框架内容元素。BindingExpression:路径= CompanyItems;DataItem =零;目标元素是“DataGridComboBoxColumn”(HashCode=28633162);目标属性是'ItemsSource'(类型为'IEnumerable')

I believe that WPF expects CompanyItems to be a property of GridItem which is not the case, and that's the reason why the binding fails.

我认为,WPF希望CompanyItems是GridItem的属性,但事实并非如此,这就是绑定失败的原因。

I've already tried to work with a RelativeSource and AncestorType like so:

我已经尝试过使用一个亲戚和祖先类型,比如:

<DataGridComboBoxColumn ItemsSource="{Binding CompanyItems, 
    RelativeSource={RelativeSource Mode=FindAncestor,
                                   AncestorType={x:Type Window}}}"
                        DisplayMemberPath="Name"
                        SelectedValuePath="ID"
                        SelectedValueBinding="{Binding CompanyID}" />

But that gives me another error in the debugger output:

但是这给我调试器输出中的另一个错误:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=CompanyItems; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=1150788); target property is 'ItemsSource' (type 'IEnumerable')

System.Windows。数据错误:4:无法找到与引用'RelativeSource FindAncestor绑定的源文件,AncestorType='System.Windows。窗口”,AncestorLevel =“1”。BindingExpression:路径= CompanyItems;DataItem =零;目标元素为“DataGridComboBoxColumn”(HashCode=1150788);目标属性是'ItemsSource'(类型为'IEnumerable')

Question: How can I bind the ItemsSource of the DataGridComboBoxColumn to the CompanyItems collection of the ViewModel? Is it possible at all?

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

Thank you for help in advance!

提前感谢您的帮助!

7 个解决方案

#1


91  

Pls, check if DataGridComboBoxColumn xaml below would work for you:

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

<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>

Here you can find another solution for the problem you're facing: Using combo boxes with the WPF DataGrid

在这里,您可以找到另一种解决问题的方法:使用组合框与WPF DataGrid

#2


37  

The documentation on MSDN about the ItemsSource of the DataGridComboBoxColumn says that only static resources, static code or inline collections of combobox items can be bound to the ItemsSource:

关于DataGridComboBoxColumn的ItemsSource的MSDN文档说明,只有静态资源、静态代码或combobox项目的内联集合可以绑定到ItemsSource:

To populate the drop-down list, first set the ItemsSource property for the ComboBox by using one of the following options:

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

  • A static resource. For more information, see StaticResource Markup Extension.
  • 一个静态的资源。有关更多信息,请参阅StaticResource标记扩展。
  • An x:Static code entity. For more information, see x:Static Markup Extension.
  • x:静态代码实体。有关更多信息,请参见x:静态标记扩展。
  • An inline collection of ComboBoxItem types.
  • ComboBoxItem类型的内联集合。

Binding to a DataContext's property is not possible if I understand that correctly.

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

And indeed: When I make CompanyItems a static property in ViewModel ...

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

public static ObservableCollection<CompanyItem> CompanyItems { get; set; }

... add the namespace where the ViewModel is located to the window ...

…将ViewModel所在的名称空间添加到窗口中……

xmlns:vm="clr-namespace:DataGridComboBoxColumnApp"

... and change the binding to ...

…并将绑定更改为…

<DataGridComboBoxColumn
    ItemsSource="{Binding Source={x:Static vm:ViewModel.CompanyItems}}" 
    DisplayMemberPath="Name"
    SelectedValuePath="ID"
    SelectedValueBinding="{Binding CompanyID}" />

... then it works. But having the ItemsSource as a static property might be sometimes OK, but it is not always what I want.

…它的工作原理。但是将ItemsSource作为静态属性有时是可以的,但它并不总是我想要的。

#3


21  

The correct solution seems to be:

正确的解决办法似乎是:

<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>

The layout above works perfectly fine for me, and should work for others. This design choice also makes sense, though it isn't very well explained anywhere. But if you have a data column with predefined values, those values typically don't change during run-time. So creating a CollectionViewSource and initializing the data once makes sense. It also gets rid of the longer bindings to find an ancestor and bind on it's data context (which always felt wrong to me).

上面的布局对我来说非常好,应该对其他人也一样。这种设计选择也有意义,尽管在任何地方都没有很好的解释。但是如果您有一个具有预定义值的数据列,那么这些值在运行时通常不会改变。因此,创建一个CollectionViewSource并初始化数据一次是有意义的。它还去掉了较长的绑定,以找到一个祖先,并绑定到它的数据上下文(我总是感觉不对)。

I am leaving this here for anyone else who struggled with this binding, and wondered if there was a better way (As this page is obviously still coming up in search results, that's how I got here).

我把这个放在这里,留给那些与此绑定有冲突的人,并想知道是否有更好的方法(因为这个页面显然仍然会出现在搜索结果中,这就是我为什么会出现在这里)。

#4


19  

I realize this question is over a year old, but I just stumbled across it in dealing with a similar problem and thought I would share another potential solution in case it might help a future traveler (or myself, when I forget this later and find myself flopping around on * between screams and throwings of the nearest object on my desk).

我意识到这个问题超过一年,但我只是偶然发现了它在处理类似的问题,我想可以分享另一个潜在的解决方案,以防它可能帮助未来的旅行者(或我自己,当我忘记这后,发现自己躺在*尖叫声和投掷之间最近的对象放在我的桌子上)。

In my case I was able to get the effect I wanted by using a DataGridTemplateColumn instead of a DataGridComboBoxColumn, a la the following snippet. [caveat: I'm using .NET 4.0, and what I've been reading leads me to believe the DataGrid has done a lot of evolving, so YMMV if using earlier version]

在我的例子中,我可以通过使用DataGridTemplateColumn而不是DataGridComboBoxColumn来获得我想要的效果。[注意:我正在使用。net 4.0,我读到的内容让我相信DataGrid已经做了很多的改进,所以如果使用早期版本的话,YMMV)

<DataGridTemplateColumn Header="Identifier_TEMPLATED">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox IsEditable="False" 
                Text="{Binding ComponentIdentifier,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                ItemsSource="{Binding Path=ApplicableIdentifiers, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ComponentIdentifier}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

#5


5  

RookieRick is right, using DataGridTemplateColumn instead of DataGridComboBoxColumn gives a much simpler XAML.

RookieRick是正确的,使用DataGridTemplateColumn而不是DataGridComboBoxColumn提供了一个简单得多的XAML。

Moreover, putting the CompanyItem list directly accessible from the GridItem allows you to get rid of the RelativeSource.

此外,将CompanyItem列表直接从GridItem访问,可以使您摆脱相对论源。

IMHO, this give you a very clean solution.

哦,这给你一个很干净的解决方案。

XAML:

XAML:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GridItems}" >
    <DataGrid.Resources>
        <DataTemplate x:Key="CompanyDisplayTemplate" DataType="vm:GridItem">
            <TextBlock Text="{Binding Company}" />
        </DataTemplate>
        <DataTemplate x:Key="CompanyEditingTemplate" DataType="vm:GridItem">
            <ComboBox SelectedItem="{Binding Company}" ItemsSource="{Binding CompanyList}" />
        </DataTemplate>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name}" />
        <DataGridTemplateColumn CellTemplate="{StaticResource CompanyDisplayTemplate}"
                                CellEditingTemplate="{StaticResource CompanyEditingTemplate}" />
    </DataGrid.Columns>
</DataGrid>

View model:

视图模型:

public class GridItem
{
    public string Name { get; set; }
    public CompanyItem Company { get; set; }
    public IEnumerable<CompanyItem> CompanyList { get; set; }
}

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

    public override string ToString() { return Name; }
}

public class ViewModel
{
    readonly ObservableCollection<CompanyItem> companies;

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

        GridItems = new ObservableCollection<GridItem> {
            new GridItem { Name = "Jim", Company = companies[0], CompanyList = companies}
        };
    }

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

#6


3  

Your ComboBox is trying to bind to bind to GridItem[x].CompanyItems, which doesn't exist.

您的ComboBox试图绑定到GridItem[x]。CompanyItems,根本不存在。

Your RelativeBinding is close, however it needs to bind to DataContext.CompanyItems because Window.CompanyItems does not exist

您的相对论绑定很接近,但是它需要绑定到DataContext。CompanyItems因为窗口。CompanyItems不存在

#7


0  

the bast way i use i bind the textblock and combobox to same property and this property should support notifyPropertyChanged.

我使用的bast方法是将textblock和combobox绑定到相同的属性,这个属性应该支持notifyPropertyChanged。

i used relativeresource to bind to parent view datacontext which is usercontrol to go up datagrid level in binding because in this case the datagrid will search in object that you used in datagrid.itemsource

我使用relativeresource绑定到父视图datacontext,它是usercontrol,用于在绑定中提升datagrid级别,因为在本例中,datagrid将在datagrid.itemsource中使用的对象中搜索

<DataGridTemplateColumn Header="your_columnName">
     <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
             <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.SelectedUnit.Name, Mode=TwoWay}" />
           </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
     <DataGridTemplateColumn.CellEditingTemplate>
           <DataTemplate>
            <ComboBox DisplayMemberPath="Name"
                      IsEditable="True"
                      ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.UnitLookupCollection}"
                       SelectedItem="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.SelectedUnit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      SelectedValue="{Binding UnitId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      SelectedValuePath="Id" />
            </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

#1


91  

Pls, check if DataGridComboBoxColumn xaml below would work for you:

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

<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>

Here you can find another solution for the problem you're facing: Using combo boxes with the WPF DataGrid

在这里,您可以找到另一种解决问题的方法:使用组合框与WPF DataGrid

#2


37  

The documentation on MSDN about the ItemsSource of the DataGridComboBoxColumn says that only static resources, static code or inline collections of combobox items can be bound to the ItemsSource:

关于DataGridComboBoxColumn的ItemsSource的MSDN文档说明,只有静态资源、静态代码或combobox项目的内联集合可以绑定到ItemsSource:

To populate the drop-down list, first set the ItemsSource property for the ComboBox by using one of the following options:

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

  • A static resource. For more information, see StaticResource Markup Extension.
  • 一个静态的资源。有关更多信息,请参阅StaticResource标记扩展。
  • An x:Static code entity. For more information, see x:Static Markup Extension.
  • x:静态代码实体。有关更多信息,请参见x:静态标记扩展。
  • An inline collection of ComboBoxItem types.
  • ComboBoxItem类型的内联集合。

Binding to a DataContext's property is not possible if I understand that correctly.

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

And indeed: When I make CompanyItems a static property in ViewModel ...

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

public static ObservableCollection<CompanyItem> CompanyItems { get; set; }

... add the namespace where the ViewModel is located to the window ...

…将ViewModel所在的名称空间添加到窗口中……

xmlns:vm="clr-namespace:DataGridComboBoxColumnApp"

... and change the binding to ...

…并将绑定更改为…

<DataGridComboBoxColumn
    ItemsSource="{Binding Source={x:Static vm:ViewModel.CompanyItems}}" 
    DisplayMemberPath="Name"
    SelectedValuePath="ID"
    SelectedValueBinding="{Binding CompanyID}" />

... then it works. But having the ItemsSource as a static property might be sometimes OK, but it is not always what I want.

…它的工作原理。但是将ItemsSource作为静态属性有时是可以的,但它并不总是我想要的。

#3


21  

The correct solution seems to be:

正确的解决办法似乎是:

<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>

The layout above works perfectly fine for me, and should work for others. This design choice also makes sense, though it isn't very well explained anywhere. But if you have a data column with predefined values, those values typically don't change during run-time. So creating a CollectionViewSource and initializing the data once makes sense. It also gets rid of the longer bindings to find an ancestor and bind on it's data context (which always felt wrong to me).

上面的布局对我来说非常好,应该对其他人也一样。这种设计选择也有意义,尽管在任何地方都没有很好的解释。但是如果您有一个具有预定义值的数据列,那么这些值在运行时通常不会改变。因此,创建一个CollectionViewSource并初始化数据一次是有意义的。它还去掉了较长的绑定,以找到一个祖先,并绑定到它的数据上下文(我总是感觉不对)。

I am leaving this here for anyone else who struggled with this binding, and wondered if there was a better way (As this page is obviously still coming up in search results, that's how I got here).

我把这个放在这里,留给那些与此绑定有冲突的人,并想知道是否有更好的方法(因为这个页面显然仍然会出现在搜索结果中,这就是我为什么会出现在这里)。

#4


19  

I realize this question is over a year old, but I just stumbled across it in dealing with a similar problem and thought I would share another potential solution in case it might help a future traveler (or myself, when I forget this later and find myself flopping around on * between screams and throwings of the nearest object on my desk).

我意识到这个问题超过一年,但我只是偶然发现了它在处理类似的问题,我想可以分享另一个潜在的解决方案,以防它可能帮助未来的旅行者(或我自己,当我忘记这后,发现自己躺在*尖叫声和投掷之间最近的对象放在我的桌子上)。

In my case I was able to get the effect I wanted by using a DataGridTemplateColumn instead of a DataGridComboBoxColumn, a la the following snippet. [caveat: I'm using .NET 4.0, and what I've been reading leads me to believe the DataGrid has done a lot of evolving, so YMMV if using earlier version]

在我的例子中,我可以通过使用DataGridTemplateColumn而不是DataGridComboBoxColumn来获得我想要的效果。[注意:我正在使用。net 4.0,我读到的内容让我相信DataGrid已经做了很多的改进,所以如果使用早期版本的话,YMMV)

<DataGridTemplateColumn Header="Identifier_TEMPLATED">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox IsEditable="False" 
                Text="{Binding ComponentIdentifier,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                ItemsSource="{Binding Path=ApplicableIdentifiers, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ComponentIdentifier}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

#5


5  

RookieRick is right, using DataGridTemplateColumn instead of DataGridComboBoxColumn gives a much simpler XAML.

RookieRick是正确的,使用DataGridTemplateColumn而不是DataGridComboBoxColumn提供了一个简单得多的XAML。

Moreover, putting the CompanyItem list directly accessible from the GridItem allows you to get rid of the RelativeSource.

此外,将CompanyItem列表直接从GridItem访问,可以使您摆脱相对论源。

IMHO, this give you a very clean solution.

哦,这给你一个很干净的解决方案。

XAML:

XAML:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GridItems}" >
    <DataGrid.Resources>
        <DataTemplate x:Key="CompanyDisplayTemplate" DataType="vm:GridItem">
            <TextBlock Text="{Binding Company}" />
        </DataTemplate>
        <DataTemplate x:Key="CompanyEditingTemplate" DataType="vm:GridItem">
            <ComboBox SelectedItem="{Binding Company}" ItemsSource="{Binding CompanyList}" />
        </DataTemplate>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name}" />
        <DataGridTemplateColumn CellTemplate="{StaticResource CompanyDisplayTemplate}"
                                CellEditingTemplate="{StaticResource CompanyEditingTemplate}" />
    </DataGrid.Columns>
</DataGrid>

View model:

视图模型:

public class GridItem
{
    public string Name { get; set; }
    public CompanyItem Company { get; set; }
    public IEnumerable<CompanyItem> CompanyList { get; set; }
}

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

    public override string ToString() { return Name; }
}

public class ViewModel
{
    readonly ObservableCollection<CompanyItem> companies;

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

        GridItems = new ObservableCollection<GridItem> {
            new GridItem { Name = "Jim", Company = companies[0], CompanyList = companies}
        };
    }

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

#6


3  

Your ComboBox is trying to bind to bind to GridItem[x].CompanyItems, which doesn't exist.

您的ComboBox试图绑定到GridItem[x]。CompanyItems,根本不存在。

Your RelativeBinding is close, however it needs to bind to DataContext.CompanyItems because Window.CompanyItems does not exist

您的相对论绑定很接近,但是它需要绑定到DataContext。CompanyItems因为窗口。CompanyItems不存在

#7


0  

the bast way i use i bind the textblock and combobox to same property and this property should support notifyPropertyChanged.

我使用的bast方法是将textblock和combobox绑定到相同的属性,这个属性应该支持notifyPropertyChanged。

i used relativeresource to bind to parent view datacontext which is usercontrol to go up datagrid level in binding because in this case the datagrid will search in object that you used in datagrid.itemsource

我使用relativeresource绑定到父视图datacontext,它是usercontrol,用于在绑定中提升datagrid级别,因为在本例中,datagrid将在datagrid.itemsource中使用的对象中搜索

<DataGridTemplateColumn Header="your_columnName">
     <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
             <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.SelectedUnit.Name, Mode=TwoWay}" />
           </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
     <DataGridTemplateColumn.CellEditingTemplate>
           <DataTemplate>
            <ComboBox DisplayMemberPath="Name"
                      IsEditable="True"
                      ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.UnitLookupCollection}"
                       SelectedItem="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.SelectedUnit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      SelectedValue="{Binding UnitId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      SelectedValuePath="Id" />
            </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>