从 ListView 项中获取 parent DataContext

Get parent DataContext from inside ListView item

我的场景: 在当前页面中,我设置了一个包含两个属性的 DataContext,第一个(页面标题)Question,第二个(项目列表)Replies.

我将 Replies 绑定到 ListViewItemsSource 属性:

<ListView x:Name="responseList" ItemsSource="{Binding replies}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <local:CustomControl />
            </DataTemplate>
        </ListView.ItemTemplate>       
    </ListView>

到目前为止没有问题。在 Custom Control 中,我还需要检索 Question 元素 (在 ListView 之外)的一些属性,将这些属性绑定到XAML 的 CustomControl.

我看了这个,但没有运气,因为 FindAncestor 在 WinRT 中不被识别: WPF Databinding: How do I access the "parent" data context?

另一个 returns 与 DataContext 完全不同:How to access Parent's DataContext in Window 8 store apps

<UserControl ....>
    <Grid Background="#33FFFFFF">
         <Grid.Resources>
              <local:converter1 x:Key="key" Question="{Binding Tag.Question, ElementName=responseList}"/>
         </Grid.Resources>
    </Grid>
</UserControl>

你可以让你的 Replies 有一个(不可变的)参考他们正在回复的问题。或者,也许更好,假设你的 DataContext 是一个 SomePageViewModel,它的 replies 列表不是你的域模型 Reply,而是 ReplyViewModel知道答案和问题的相关部分。

这实际上并没有回答您的问题,但设计要好得多,确实解决了问题。

在不更改您的 Reply 域模型的情况下构建此结构的一种方法如下:

// Domain Model example
class Question
{
    public String Text { get; set; }
    public String Author { get; set; 
    public IEnumerable<Reply> Replies { get; set; }
}

// Domain Model example
class Reply
{
    public String Author { get; set; }  
    public String Text { get; set; }
}

// DataContext example
class WhatYouUseAsDataContext
{
    public Question Question { get; set; } 

    // Your replies -- this is what your ListView binds to.
    public IEnumerable<ReplyViewModel> Replies { get; set; } 

    public WhatYouUseAsDataContext()
    {
        Question = SomeWayToGetTheQuestion();
        Replies = Question.Replies.Select(reply => new ReplyViewModel()
        {
            Reply = reply,
            QuestionAuthor = Question.Author
        });
    }
}

// Newly introduced viewmodel class
class ReplyViewModel
{
    public Reply Reply { get; set; }
    public String QuestionAuthor { get; set; }
}