这是绑定(bind)到列的类。我在 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 绑定(bind)正在工作,如附图所示。
<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 Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MasksSourceListBound.ListParts; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=64358720); target property is 'ItemsSource' (type 'IEnumerable')
我已经尝试过这个,但仍然没有结果:
<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)
Here is the corrected XAML Decided to explicitly set the datacontext for DataGrid to avoid 3 part binding. But still getting Input String was not in correct format in break mode. The output indicates RelativeSource (FindAncestor) requires tree context:
<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>
最佳答案
所以我们已经成功了一半。 ElementStyle 和 EditingElementStyle 中的绑定(bind)的 DataContext
是行项 - MaskDetail
(在您的情况下)。我的猜测是这个绑定(bind):
Value="{Binding MasksViewModel.MasksSourceListBound.ListParts}"
...意味着建议绑定(bind)应该找到 MasksViewModel
类型的 View 模型并使用其中的指定属性。
一方面,这不是绑定(bind)的工作原理。它们有一个 DataContext
,如果您没有显式指定 Source
或 RelativeSource
,它们会在那里查找属性。该绑定(bind)所发生的情况是,它正在查看一个 MaskDetail
,即您用于填充网格的行项目类,其名称为 MasksViewModel
的属性。我认为没有,否则这会起作用。
以下是找出绑定(bind)失败原因的方法:
Value="{Binding MasksViewModel.MasksSourceListBound.ListParts, PresentationTraceSources.TraceLevel=High}"
然后在运行时观察 VS 中的输出 Pane 。当绑定(bind)尝试查找 MasksViewModel.MasksSourceListBound.ListParts
时,您将获得每个步骤的跟踪,并且您将看到失败的位置和原因。
因此,在元素样式中,您要做的就是绑定(bind)到 ListParts
,它是 MasksSourceListBound
的属性,而后者又是主视图模型的属性 - - 这是 DataGrid
的 DataContext
。
因此,我们在可视化树中搜索 DataGrid
,获取其 DataContext
,然后在其中查找 MasksSourceListBound.ListParts
:
<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>
它并不漂亮,但它始终如一地工作,这就是我们在 WPF 中做事的方式。
更新
这是我的 XAML 的更完整图片。我没有完全重现你的整个事情。重要的部分是相对源绑定(bind):我可以使用以下 XAML 绑定(bind)到 DataGrid 的 DataContext 的属性。 DataGrid 的 DataContext 是对主视图模型的引用 - 拥有 MasksSourceListBound.MaskDetails
的同一对象。
<DataGrid
ItemsSource="{Binding MasksSourceListBound.MaskDetails}"
>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding OtherTestProperty}" />
<DataGridComboBoxColumn
Header="Test"
SelectedItemBinding="{Binding SelectedItem}"
>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter
Property="ItemsSource"
Value="{Binding DataContext.MasksSourceListBound.ListParts, RelativeSource={RelativeSource AncestorType=DataGrid}, PresentationTraceSources.TraceLevel=High}"
/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.MasksSourceListBound.ListParts, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
关于c# - DataGridComboBoxColumn ItemsSource 列表未找到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44463000/