将集合绑定到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>
现在我不知道,我怎么能绑定ItemsSource的ComboBox,这样我就可以读取list的list值在我的X类?
然后我不知道什么是实际上我的FieldName的功能列?我输入ListY,因为它表示X类中的属性(IList<>)。但我认为这可能是不对的。
谢谢你的帮助!
要回答你的第一个问题,试试这个
<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;
}
我需要的数据是可用的,但是视图没有显示它。