未找到DataGridComboBoxColumn ItemsSource List

时间:2017-06-09 16:46:21

标签: c# wpf datagrid

这是绑定到列的类。我在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;)

enter image description here

我试过这个但是仍然没有结果:

<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>

1 个答案:

答案 0 :(得分:2)

所以我们已经到了一半。在您的情况下,ElementStyle和EditingElementStyle中绑定的DataContext是行项MaskDetail。我猜这个绑定:

Value="{Binding MasksViewModel.MasksSourceListBound.ListParts}"

...意味着建议绑定应该找到类型为MasksViewModel的视图模型并使用其中的指定属性。

一方面,这不是绑定的工作方式。他们有DataContext,如果您没有明确指定SourceRelativeSource,他们会在那里寻找属性。该绑定发生的是它正在查看MaskDetail,即用于填充网格的行项类,用于名为MasksViewModel的属性。我不认为有一个,或者这会起作用。

这是一种找出绑定失败原因的方法:

Value="{Binding MasksViewModel.MasksSourceListBound.ListParts, PresentationTraceSources.TraceLevel=High}"

然后在运行时观察VS中的输出窗格。当绑定试图找到MasksViewModel.MasksSourceListBound.ListParts时,您将获得每个步骤的跟踪,并且您将看到它失败的位置和原因。

所以你想要做的,在元素样式中,绑定到ListPartsMasksSourceListBound的属性,它又是主视图模型的属性 - 即{{ 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