当在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>
现在我不知道,如何绑定ComboBox的ItemsSource,以便我可以在X类中读取ListY的列表值?
然后我不知道函数列的实际内容是什么? 我输入了ListY,因为它代表了我的X类中的属性(IList&lt;&gt;)。但我认为这可能不对。
非常感谢你的帮助!
答案 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
property到ItemsSource
的设置毫无意义。从链接页面:
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;
}
我需要的数据可用,但视图没有显示。我不知道我没有考虑过。