You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Caliburn.Micro:如何将父级Question的DataContext传递给ViewModel方法

解决Caliburn.Micro嵌套ListView中传递父级Question的问题

你当前的问题是点击Answer列表里的按钮时,传递的是Answer的DataContext,而需要的是它所属的父级Question对象。以下几种方案可以解决这个问题:

方案1:使用Caliburn.Micro内置的$parent语法

Caliburn.Micro支持在Message.Attach中通过$parent直接访问当前DataContext的父级上下文。修改按钮的XAML代码如下:

<Button cm:Action.TargetWithoutContext="{Binding DataContext, ElementName=Questions}" 
        cm:Message.Attach="Show($parent)" />

这里$parent会指向Answer所在的父级DataContext(也就是Question对象),同时Action.TargetWithoutContext确保方法调用的是主ViewModel中的Show方法。

方案2:通过ElementName绑定父级DataContext

在父级Question的DataTemplate里给容器控件命名,直接绑定它的DataContext作为参数:
首先修改父级DataTemplate中的Grid:

<!-- 给Question的容器Grid添加Name -->
<Grid Name="QuestionContainerGrid">
    <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({Binding DataContext, ElementName=QuestionContainerGrid})" />
                    <TextBox Grid.Column="1" Text="{Binding Text}" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

这种方式不依赖Caliburn的特殊语法,通过WPF原生的ElementName绑定获取父级Question的DataContext。

方案3:扩展模型添加父级引用

如果允许修改模型结构,可以给Answer类添加一个指向父级Question的属性,在初始化时关联:

public class Answer 
{
    public string Text { get; set; }
    public Question ParentQuestion { get; set; } // 添加父级Question引用
}

创建Question时,给每个Answer设置父级:

// 示例初始化代码
var sampleQuestion = new Question
{
    Id = 1,
    Text = "示例问题",
    Answers = new List<Answer>
    {
        new Answer { Text = "选项1", ParentQuestion = sampleQuestion },
        new Answer { Text = "选项2", ParentQuestion = sampleQuestion }
    }
};
Questions.Add(sampleQuestion);

之后按钮的参数可以直接绑定这个属性:

<Button cm:Action.TargetWithoutContext="{Binding DataContext, ElementName=Questions}" 
        cm:Message.Attach="Show($dataContext.ParentQuestion)" />

这种方案适合需要在模型层维护父子关系的场景,后续业务逻辑也能直接通过Answer访问父级Question。

内容的提问来源于stack exchange,提问作者Reydan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 17:01:07