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

WPF嵌套DataGrid:如何获取InnerGrid的SelectedItem?

解决嵌套DataGrid中InnerGrid SelectedItem绑定失效的问题(Caliburn.Micro环境)

我之前也碰到过一模一样的问题,核心原因大多是绑定上下文不对或者属性变更通知没做好,结合你用Caliburn.Micro的情况,给你几个可行的解决方案:

方案1:修正绑定路径(当SelectedInner是根ViewModel的属性时)

你的InnerGrid默认的DataContext是外层DataGrid的单条行数据(也就是OuterGrid集合里的某个对象),如果SelectedInner是定义在根ViewModel里的,直接写{Binding SelectedInner}肯定找不到这个属性,得通过RelativeSource指定上下文:

<DataGrid ItemsSource="{Binding InnerGrid}" 
          SelectedItem="{Binding DataContext.SelectedInner, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
          SelectionMode="Single">
    <!-- 列定义 -->
</DataGrid>

这里通过RelativeSource找到外层的DataGrid,它的DataContext就是你的根ViewModel,这样就能正确绑定到根级别的SelectedInner属性了。

方案2:把SelectedInner放到外层行对象中(更贴合MVVM的拆分)

如果业务上每个外层行对应的InnerGrid选中项应该属于该行数据,那可以把SelectedInner定义在外层行的模型类里,同时要确保这个模型继承Caliburn.Micro的PropertyChangedBase,这样属性变更才能通知UI:

外层行模型类

public class OuterGridItem : PropertyChangedBase
{
    // 内层集合
    public IEnumerable<InnerGridItem> InnerGrid { get; set; }

    private InnerGridItem _selectedInner;
    public InnerGridItem SelectedInner
    {
        get => _selectedInner;
        // 用Caliburn的Set方法自动触发PropertyChanged
        set => Set(ref _selectedInner, value);
    }
}

这种情况下你原来的绑定代码SelectedItem="{Binding SelectedInner}"就是正确的,只要模型类正确实现了属性变更通知,选中后SelectedInner就会被赋值。

方案3:用Caliburn.Micro的消息机制直接处理事件

如果不想纠结绑定路径,也可以用Caliburn的Message.Attach来绑定InnerGrid的SelectionChanged事件,直接在ViewModel里拿到选中项:

XAML代码

<DataGrid ItemsSource="{Binding InnerGrid}" 
          cal:Message.Attach="[Event SelectionChanged] = [Action HandleInnerSelectionChanged($eventArgs)]">
    <!-- 列定义 -->
</DataGrid>

根ViewModel里的处理方法

public class MainViewModel : Screen
{
    private InnerGridItem _selectedInner;
    public InnerGridItem SelectedInner
    {
        get => _selectedInner;
        set => Set(ref _selectedInner, value);
    }

    public void HandleInnerSelectionChanged(SelectionChangedEventArgs e)
    {
        // 取第一个选中的项(如果是单选模式)
        if (e.AddedItems.Count > 0)
        {
            SelectedInner = e.AddedItems[0] as InnerGridItem;
        }
    }
}

额外注意点

  • 确保InnerGrid的SelectionMode设置为Single(默认就是),如果是Extended或Multiple,SelectedItem只会返回第一个选中项,或者你需要用SelectedItems集合。
  • 根ViewModel要继承Caliburn的Screen或PropertyChangedBase,确保属性变更能通知UI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 16:02:49