如何绑定DataGrid到更多的集合?

How to bind DataGrid to more collections?

我有一个绑定到 ObservableCollection 的 DataGrid (StoredSequences<Sequence>):

<DataGrid ItemsSource="{Binding StoredSequences}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ID}" >
                <DataGridTextColumn.ElementStyle>
                    <Style>
                        <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                        <Setter Property="TextBlock.TextAlignment" Value="Center"/>
                    </Style>
                </DataGridTextColumn.ElementStyle>
            </DataGridTextColumn>
            <DataGridTextColumn Binding="{Binding NameEnglish}" >
                <DataGridTextColumn.ElementStyle>
                    <Style>
                        <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                    </Style>
                </DataGridTextColumn.ElementStyle>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

序列模型:

public class Sequence : INotifyPropertyChanged
{
    public Sequence() { }

    private int _id;
    public int ID
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
            OnPropertyChanged("ID");
        }
    }
    private string _nameEnglish;
    public string NameEnglish
    {
        get
        {
            return _nameEnglish;
        }
        set
        {
            _nameEnglish = value;
            OnPropertyChanged("NameEnglish");
        }
    }
    private int _value;
    public int Value
    {
        get
        {
            return _value;
        }
        set
        {
            _value= value;
            OnPropertyChanged("Value");
        }
    }
    private string _category;
    public string Category
    {
        get
        {
            return _category;
        }
        set
        {
            _category = value;
            OnPropertyChanged("Category");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

我想在网格的最后两列中添加两个 ComboBox,ItemsSource 绑定到其他 ObservableCollections(Values<int>Categories<string> 在 ViewModel 中生成)。我可以添加文本框,因为 Sequence 包含 ValueCategory,但我希望用户能够 select 项目。我试过这个:

                <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="ComboBox1" ItemsSource="{Binding Values}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="ComboBox2" ItemsSource="{Binding Categories}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

问题是组合框是空的。这是收到的错误之一:

System.Windows.Data Error: 40 : BindingExpression path error: 'Values' property not found on 'object' ''Sequence' (HashCode=31195541)'. BindingExpression:Path=Values; DataItem='Sequence' (HashCode=31195541); target element is 'ComboBox' (Name=ComboBox1'); target property is 'ItemsSource' (type 'IEnumerable')

将 DataGrid 绑定到更多集合的正确方法是什么?或者如何在 CellEdit 和 TextBox 上显示组合框?

您可以从错误消息中看出绑定失败,因为框架无法在 Sequence 类型的对象上找到 Values 和 Categories 属性。发生这种情况是因为您的 DataGrid 中的每一行都有底层序列作为其 DataContext。

如果您不想将 Values 和 Categories 集合添加到 Sequence 对象,那么您需要做的是更改您的 Bindings,以便它们绑定到父 DataContext,而不是行 DataContext。

试试这个例子,它将绑定重定向到 DataGrid 的 DataContext:

        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox x:Name="ComboBox2" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.Categories}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>