WPF - Binding error in DataGridComboboxColumn

2019-09-11 00:29发布

I am in a need of using DataGridComboboxColumn in my dataGrid. But the observable collection I am going to bind to my datagrid is not static ?

is it necessary for that Observale collection to be static since the data grid contains a DataGridComboboxColumn.

What I am going to bind to the DataGridCombobox column is another collection contained in the class of which objects are there in the observable collection I mentioned above. This is the first time I am using DataGridCombobox column. Any explanation will be much appreciated.

<DataGrid ItemSource="{Binding SomeData}">
    <DataGrid.Columns>
        <DataGridTemplateColumn DisplayMemberPath="FirstName" />
        <DataGridTemplateColumn DisplayMemberPath="LastName"  />
        <DataGridComboboxColumn ItemSource={Binding SomeOtherListContainedInSomeDataAbove}" />
    </DataGrid.Columns>
<DataGrid>

But this generates binding errors and says that SomeOtherListContainedInSomeDataAbove cannot be found.

pls help.

2条回答
爷、活的狠高调
2楼-- · 2019-09-11 00:52

DataGridComboboxColumn does not Participate in Logical Tree and hence it hard to do bind for its ItemsSource Directly. But DataGridCell is part of the Logical Tree. You can Create an Element Style and try to bind your collection. In the below sample I have given two approaches using DataGridComboBoxColumn and DatagridTemplateColumn. I am assuming you are using MVVM.

<DataGrid ItemsSource="{Binding DataGrdList}" AutoGenerateColumns="False">            
        <DataGrid.Columns>
            <DataGridComboBoxColumn SelectedItemBinding="{Binding DataTypeName}"  Header="Combo">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.DataTypeList}"/>
                        <Setter Property="IsReadOnly" Value="True"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.DataTypeList}"/>
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
            <DataGridTemplateColumn Header="Template">
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox SelectedValue="{Binding Path=DataTypeName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext.DataTypeList}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=DataTypeName, UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>

    </DataGrid>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainViewModel();
    }
}

public class MainViewModel
{
    private ObservableCollection<string> myVar = new ObservableCollection<string>();

    public ObservableCollection<string> DataTypeList
    {
        get { return myVar; }
        set { myVar = value; }
    }

    private ObservableCollection<DataType1> myVar1 = new ObservableCollection<DataType1>();

    public ObservableCollection<DataType1> DataGrdList
    {
        get { return myVar1; }
        set { myVar1 = value; }
    }

    public MainViewModel()
    {
        myVar.Add("Int");
        myVar.Add("Bool");
        myVar.Add("String");  
    }   
}

public class DataType1
{
    private string name;

    public string DataTypeName
    {
        get { return name; }
        set { name = value; }
    }  
}
查看更多
forever°为你锁心
3楼-- · 2019-09-11 01:18

Have you tried :

<DataGridComboboxColumn ItemSource={Binding path=SomeOtherListContainedInSomeDataAbove}"> 

If your context for the binding is the SomeData, this should point it to the right property)

From MSDN:

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

  • A static resource. For more information, see StaticResource Markup Extension.

  • An x:Static code entity. For more information, see x:Static Markup Extension.

  • An inline collection of ComboBoxItem types.

Once the ItemsSource is set, bind the selected item in the ComboBox to the data item for the row that the cell is in. You can set the binding by using one of the following properties....

So, if it's not static, I'd say try option 3 :)

查看更多
登录 后发表回答