将集合绑定到DataGrid中的ComboBox

时间:2014-03-21 10:22:41

标签: c# wpf datagrid combobox

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

我有一大堆课程,我希望在xceed DataGrid中显示他们的数据。我的DataContext设置为ViewModelClass。它有一个X类对象列表:

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

X类看起来像这样。它有一个属性Id和一个Y类对象的列表。 该列表应该是我的ComboBoxes的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; }
}

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

<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. 现在我不知道,如何绑定ComboBox的ItemsSource,以便我可以在X类中读取ListY的列表值?

  2. 然后我不知道函数列的实际内容是什么? 我输入了ListY,因为它代表了我的X类中的属性(IList&lt;&gt;)。但我认为这可能不对。

  3. 非常感谢你的帮助!

3 个答案:

答案 0 :(得分:0)

回答你的第一个问题 - 试试这个

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

对于你的秒问题,我不太确定(这取决于你),但是字段名称可能是SelectedFunction或其他类似的东西

答案 1 :(得分:0)

让我们将你的问题分解成一口大小的碎片。您有一个ListX集合,该集合是绑定到DataGrid.ItemsSource属性的数据:

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

在此阶段,有关您的代码的一点需要注意的是,PropertyChanged属性上Binding.UpdateSourceTrigger propertyItemsSource的设置毫无意义。从链接页面:

  

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

确实应该知道代码在使用之前所做的事情。

无论如何,回到你的问题......我们有一个数据绑定DataGrid,其中一个列中有一个ComboBox。我不确定你为什么不使用DataGridComboBoxColumn Class或同等版本,但无论如何。现在,您需要了解有关所有集合控件的内容:

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

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

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

我无法确认您设置的SelectedValuePath是否有效,因为您没有在任何地方提及它,但是如果您的班级Y没有名为{{1}的属性在其中,它将工作。你还必须更好地解释你的第二个问题,因为我真的不明白它。

答案 2 :(得分:0)

我找到了一个解决方案,但即使这样也没有证明是有效的。因为在我的视图中对charboBox.ItemsSource的cell.Content的分配显示没有效果: - (

在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;
}

我需要的数据可用,但视图没有显示。我不知道我没有考虑过。