Caliburn.Micro: Pass the parent DataContext property to the viewmodel

128 views Asked by At

I'm using Caliburn.micro in my WPF project. Model has two classes:

public class Question
{
    public int Id {get; set;}
    public string Text { get; set; }
    public List<Answer> Answers { get; set; }
}
public class Answer 
{
    public string Text { get; set; }
}

The viewmodel has a collection of Questions and a method for displaying the text of the question (for example):

public ObservableCollection<Question> Questions { get; set; } = new ObservableCollection<Question>();
public void Show(object obj)
{
    if (obj is Question question)
        MessageBox.Show(question.Text);
}

In view, a ListView is bound to this collection:

<ListView Name="Questions" ItemsSource="{Binding Questions}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <TextBox Grid.Row="0" Text="{Binding Text}" />
                <ListView Name="Answers" ItemsSource="{Binding Answers}" Grid.Row="1">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="auto" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <Button cm:Action.TargetWithoutContext="{Binding DataContext, ElementName=Questions}" cm:Message.Attach="Show($dataContext)" />
                                <TextBox Grid.Column="1" Text="{Binding Text}" />
                            </Grid>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

The difficulty is that when I click on a button in the list of answers, I need to pass not the DataContext of the current answer, but the DataContext of the question in which this answer is located, to the Show($dataContext) method. How can I do that? <Button cm:Action.TargetWithoutContext="{Binding DataContext, ElementName=Questions}" cm:Message.Attach="Show($dataContext)" /> I want to pass the parent object Question. I would be grateful for any help.

1

There are 1 answers

1
mm8 On

You could try to bind to the parent ListView using a RelativeSource:

cm:Action.TargetWithoutContext="{Binding DataContext,
    RelativeSource={RelativeSource AncestorType=ListView}}"