首页 文章

将集合绑定到DataGrid中的ComboBox

提问于
浏览
0

当在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-Code看起来像这样 .

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

  • 然后我不知道函数列实际上是什么字段名?我输入了ListY,因为它代表了我的X类中的属性(IList <>) . 但我认为这可能不对 .

非常感谢你的帮助!

3 回答

  • 0

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

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

    对于你的秒问题,我不太确定(这取决于你)但字段名称可能是SelectedFunction或沿着这些行的东西

  • 0

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

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

    关于你的代码在这个阶段需要注意的一点是,在 ItemsSource 属性上将Binding.UpdateSourceTrigger property设置为 PropertyChanged 毫无意义 . 从链接页面:

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

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

    所以无论如何,回到你的问题......我们有一个数据绑定 DataGrid ,其中一个列中有一个 ComboBox . 我'm not really sure why you'不使用DataGridComboBoxColumn Class或同等物,但无论如何 . 现在,您需要了解有关所有集合控件的内容:

    如果类型 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 的属性,那么它将无效 . 你真的明白了 .

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

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

相关问题