将集合绑定到DataGrid中的ComboBox

本文关键字:中的 ComboBox DataGrid 集合 绑定 | 更新日期: 2023-09-27 17:51:10

当ComboBox在DataGrid中实现时,我有两个关于将ComboBox绑定到列表对象的问题。但他们是如此的相互关联,我认为两个线程是没有建设性的。

我有很多类,我想在一个超越DataGrid中显示它们的数据。我的DataContext被设置为ViewModelClass。它有一个类X对象的列表:

public class ViewModelClass
{
    public IList<X> ListX { get; set; }
}

类X看起来像这样。它有一个属性Id和一个类Y对象的列表列表。列表应该是我的ItemsSource的组合框(在DataGrid)。

public class X
{
     public int Id { get; set; }
     // this should be my ItemsSource for the ComboBoxes
     public IList<Y> ListY { get; set; }
}

类Y和Z看起来是这样的。它们是一些非常简单的类:

public class Y
{
     public Z PropZ { get; set; }
}
public class Z
{
     public string Name { get; set; }
}

我的xhtml代码看起来像这样。

<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="ListX" AutoCreateItemProperties="False"
                                   Source="{Binding Path=ListX,
                                                    UpdateSourceTrigger=PropertyChanged,
                                                    Mode=TwoWay}" />
</Grid.Resources>
<p:DataGrid AutoCreateColumns="False"
            ItemsSource="{Binding Source={StaticResource ListX},
                                  UpdateSourceTrigger=PropertyChanged}">
    <xcdg:Column Title="Id" FieldName="Id" />
    <xcdg:Column Title="Functions" **FieldName="ListY"**>
        <xcdg:Column.CellContentTemplate>
            <DataTemplate>
                <ComboBox DisplayMemberPath="PropZ.Name"
                          **ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type xcdg:DataGridControl}}, Path=ItemsSource.ListY**}"                                      SelectedValuePath="Funktion.FunktionId" />
            </DataTemplate>
        </xcdg:Column.CellContentTemplate>
    </xcdg:Column>
  1. 现在我不知道,我怎么能绑定ItemsSource的ComboBox,这样我就可以读取list的list值在我的X类?

  2. 然后我不知道什么是实际上我的FieldName的功能列?我输入ListY,因为它表示X类中的属性(IList<>)。但我认为这可能是不对的。

谢谢你的帮助!

将集合绑定到DataGrid中的ComboBox

要回答你的第一个问题,试试这个

<ComboBox ItemsSource="{Binding Path=DataContext.ListY, 
 RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"

对于你的第二个问题我不太确定(这取决于你)但字段名可能是SelectedFunction或沿着这些行

让我们把你的问题分解成小块。您有一个ListX集合,它的数据绑定到DataGrid.ItemsSource属性:

<DataGrid ItemsSource="{Binding ListX}" ... />

关于此阶段的代码需要注意的一件事是,将ItemsSource属性上的Binding.UpdateSourceTrigger属性设置为PropertyChanged是没有意义的。从链接页面:

TwoWay或OneWayToSource的绑定监听目标属性中的更改,并将其传播回源。这被称为更新源。通常,只要目标属性发生更改,就会发生这些更新。这对于复选框和其他简单控件很好,但对于文本字段通常不合适。每次击键后进行更新会降低性能,而且它剥夺了用户在提交新值之前退格和修复输入错误的通常机会。因此,Text属性的默认UpdateSourceTrigger值是LostFocus而不是PropertyChanged。

真的应该知道代码的作用在你使用它之前

无论如何,回到你的问题…我们有一个数据绑定DataGrid,其中一列中有一个ComboBox。我真的不知道为什么你不使用DataGridComboBoxColumn类或同等的,但没关系。现在,您需要了解关于所有集合控件的一些信息:

如果一个类型为A的集合被数据绑定到一个集合控件的ItemsSource属性上,那么这个集合控件的每一项都将是一个类型为A的实例。这意味着每个项目的DataContext将被设置为A类型的实例。这意味着我们可以从任何DataTemplate中访问A类中定义的所有属性,这些属性定义了每个项目的外观。

这意味着您可以从DataTemplate中直接访问X类的ListY属性,该属性定义了您的项目应该是什么样子。因此,应该能够这样做:

<DataTemplate>
    <ComboBox DisplayMemberPath="PropZ.Name" ItemsSource="{Binding ListY}" 
        SelectedValuePath="Funktion.FunktionId" />
</DataTemplate>

我不能确认你设置的SelectedValuePath是否会工作,因为你没有在任何地方提到它,但是如果你的类Y没有一个名为Funktion的属性,那么它将工作。你还必须更好地解释你的第二个问题,因为我没有真正理解它。

我已经找到了一个解决方案,但即使这样也没有被证明是有效的。因为单元格的分配。内容到组合框。ItemsSource在我的视图中没有显示效果:-(

)在XAML中,我有以下代码
<xcdg:Column.CellContentTemplate>
    <DataTemplate>
        <p:XDataGridComboBox 
            DataRow="{Binding RelativeSource={RelativeSource AncestorType={x:Type xcdg:DataRow}}}" 
            ItemsFieldName="Functions" />
    </DataTemplate>
</xcdg:Column.CellContentTemplate>

我已经编写了一个自定义控件,其中我显式地设置了每个ComboBox的数据源:

static XDataGridComboBox()
{
    DataRowProperty = DependencyProperty.RegisterAttached(
        "DataRow",
        typeof(DataRow),
        typeof(XDataGridComboBox),
        new FrameworkPropertyMetadata(OnChangeDataRow));
        ItemsFieldNameProperty = DependencyProperty.RegisterAttached(
            "ItemsFieldName",
            typeof(string),
            typeof(XDataGridComboBox),
            new FrameworkPropertyMetadata(OnChangeItemsFieldName));
}
private static void OnChangeDataRow(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var comboBox = d as XDataGridComboBox;
    if (comboBox == null)
    {
        return;
    }
    var cell =
        (from DataCell c in comboBox.DataRow.Cells where c.FieldName == comboBox.ItemsFieldName select c)
            .FirstOrDefault();
    if (cell == null)
    {
        return;
    }
    comboBox.ItemsSource = cell.Content as IEnumerable;
}

我需要的数据是可用的,但是视图没有显示它。