这是绑定到列的类。我在ListParts上设置了一个监视器,这些部件确实存在。
private MasksSourceList _MasksSourceListBound;
public MasksSourceList MasksSourceListBound
{
get => _MasksSourceListBound;
set { SetAndNotify(ref _MasksSourceListBound, value, () => MasksSourceListBound); }
}
public class MasksSourceList : ObservableObject
{
private List<MaskDetail> _maskDetails;
public List<MaskDetail> MaskDetails
{
get => _maskDetails;
set { SetAndNotify(ref _maskDetails, value, () => MaskDetails); }
}
private List<Jarvis.Data.Models.Parts> _listParts;
public List<Jarvis.Data.Models.Parts> ListParts
{
get => _listParts;
set { SetAndNotify(ref _listParts, value, () => ListParts); }
}
}
以下是显示DataGrid的父项源的XAML。
<DataGrid ItemsSource="{Binding MasksSourceListBound.MaskDetails}" >
我正在显示一个普通的文本列,以演示DataGrid的ItemsSource绑定是否正常工作,如附图所示。
<DataGrid.Columns>
<DataGridTextColumn Header="part name" Binding="{Binding PartName}">
</DataGridTextColumn>
<DataGridComboBoxColumn
Header="part name"
ItemsSource="{Binding MasksSourceListBound.ListParts}"
SelectedValueBinding="{Binding PartName, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="PartId"
DisplayMemberPath="PartName"
>
</DataGridComboBoxColumn>
但为什么组合框列的ItemsSource无法识别ListParts?我检查了PartId和PartName的拼写,它们是正确的。
以下是输出窗口中的错误消息:
System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= MasksSourceListBound.ListParts;的DataItem = NULL;目标元素是&#39; DataGridComboBoxColumn&#39; (的HashCode = 64358720);目标属性是&#39; ItemsSource&#39; (键入&#39; IEnumerable&#39;)
我试过这个但是仍然没有结果:
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding MasksViewModel.MasksSourceListBound.ListParts}"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding MasksViewModel.MasksSourceListBound.ListParts}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
使用具有适当相对来源等的DataContext.MasksSourceListBound.ListParts修改上述内容后,跟踪器显示:
System.Windows.Data Warning: 58 : Path: 'DataContext.MasksSourceListBound.ListParts'
System.Windows.Data Warning: 60 : BindingExpression (hash=20088760): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=20088760): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=20088760): Attach to System.Windows.Controls.DataGridComboBoxColumn+TextBlockComboBox.ItemsSource (hash=46581119)
System.Windows.Data Warning: 66 : BindingExpression (hash=20088760): RelativeSource (FindAncestor) requires tree context
System.Windows.Data Warning: 65 : BindingExpression (hash=20088760): Resolve source deferred
System.Windows.Data Warning: 67 : BindingExpression (hash=5618098): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=5618098): Found data context element: <null> (OK)
这是更正后的XAML 决定为DataGrid显式设置datacontext以避免3部分绑定。但仍然在中断模式下获取输入字符串的格式不正确。输出表明RelativeSource(FindAncestor)需要树上下文:
<DataGrid DataContext="{Binding MasksSourceListBound}" ItemsSource="{Binding MaskDetails}"
<DataGridComboBoxColumn Header="part name" HeaderStringFormat=" {0}" Width="200"
SelectedValueBinding="{Binding PartName, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="PartId"
DisplayMemberPath="PartName">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter
Property="ItemsSource"
Value="{Binding DataContext.ListParts, RelativeSource={RelativeSource AncestorType=DataGrid}, PresentationTraceSources.TraceLevel=High}"
/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter
Property="ItemsSource"
Value="{Binding DataContext.ListParts, RelativeSource={RelativeSource AncestorType=DataGrid}, PresentationTraceSources.TraceLevel=High}"
/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
答案 0 :(得分:2)
所以我们已经到了一半。在您的情况下,ElementStyle和EditingElementStyle中绑定的DataContext
是行项MaskDetail
。我猜这个绑定:
Value="{Binding MasksViewModel.MasksSourceListBound.ListParts}"
...意味着建议绑定应该找到类型为MasksViewModel
的视图模型并使用其中的指定属性。
一方面,这不是绑定的工作方式。他们有DataContext
,如果您没有明确指定Source
或RelativeSource
,他们会在那里寻找属性。该绑定发生的是它正在查看MaskDetail
,即用于填充网格的行项类,用于名为MasksViewModel
的属性。我不认为有一个,或者这会起作用。
这是一种找出绑定失败原因的方法:
Value="{Binding MasksViewModel.MasksSourceListBound.ListParts, PresentationTraceSources.TraceLevel=High}"
然后在运行时观察VS中的输出窗格。当绑定试图找到MasksViewModel.MasksSourceListBound.ListParts
时,您将获得每个步骤的跟踪,并且您将看到它失败的位置和原因。
所以你想要做的,在元素样式中,绑定到ListParts
,MasksSourceListBound
的属性,它又是主视图模型的属性 - 即{{ 1}} DataGrid
。
因此,我们将可视树搜索到DataContext
,获取DataGrid
,然后查看DataContext
:
MasksSourceListBound.ListParts
它不漂亮,但它的工作始终如一,这就是我们在WPF中做事的方式。
这是我的XAML的更完整图片。我没有完全重建你的整个事情。重要的部分是相对源绑定:我可以使用以下XAML绑定到DataGrid的DataContext的属性。 DataGrid的DataContext是对主视图模型的引用 - 与拥有<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter
Property="ItemsSource"
Value="{Binding DataContext.MasksSourceListBound.ListParts, RelativeSource={RelativeSource AncestorType=DataGrid}}"
/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter
Property="ItemsSource"
Value="{Binding DataContext.MasksSourceListBound.ListParts, RelativeSource={RelativeSource AncestorType=DataGrid}}"
/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
的同一对象。
MasksSourceListBound.MaskDetails