如何在DataGridRow数据模板中绑定Window命令并传递行对象参数
问题分析
错误提示说明MenuItem的Command绑定到了行数据对象SnapshotWrapper,但ExportHb命令实际存在于Window的DataContext中。原因是ContextMenu是独立的弹出元素,不属于VisualTree,常规的相对源/元素名绑定无法直接找到Window的上下文,导致默认继承了DropDownButton的行数据上下文。
解决方案
方法1:通过Tag传递Window的DataContext
这种方法避免了VisualTree查找的限制,通过DropDownButton的Tag属性携带Window的上下文,再在ContextMenu中访问:
- 修改
DropDownButton,将Tag绑定到Window的DataContext:
<btn:DropDownButton MainImage="/Pollination.Core;Component/Resources/16x16/export.png" HoverImage="/Pollination.Core;Component/Resources/16x16/exportHover.png" VerticalAlignment="Center" Cursor="Hand" Width="15" Height="15" Margin="5,0,1,0" ToolTip="" <!-- 绑定Tag到Window的DataContext --> Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}">
- 修改
ContextMenu和MenuItem的绑定:
<btn:DropDownButton.Menu> <ContextMenu> <MenuItem <!-- 从ContextMenu的PlacementTarget(即DropDownButton)的Tag中获取命令 --> Command="{Binding PlacementTarget.Tag.ExportHb, RelativeSource={RelativeSource AncestorType=ContextMenu}}" <!-- CommandParameter绑定当前行的SnapshotWrapper对象 --> CommandParameter="{Binding}" Header='Honeybee Model *.hbjson'/> </ContextMenu> </btn:DropDownButton.Menu>
方法2:使用{x:Reference}直接引用Window
如果Window有明确的x:Name(例如x:Name="MainWindow"),可以直接引用Window的DataContext:
<btn:DropDownButton.Menu> <ContextMenu> <MenuItem Command="{Binding DataContext.ExportHb, Source={x:Reference MainWindow}}" CommandParameter="{Binding}" Header='Honeybee Model *.hbjson'/> </ContextMenu> </btn:DropDownButton.Menu>
注意:这种方法可能引发循环引用警告,若出现此问题优先使用方法1。
修改后的完整DataGrid模板列代码
<DataGridTemplateColumn Header="Actions" Width="100" HeaderStyle="{StaticResource CenterGridHeaderStyle}"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Grid x:Name="RoomNameGrid" HorizontalAlignment="Stretch" Background="Transparent"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <btn:DropDownButton MainImage="/Pollination.Core;Component/Resources/16x16/export.png" HoverImage="/Pollination.Core;Component/Resources/16x16/exportHover.png" VerticalAlignment="Center" Cursor="Hand" Width="15" Height="15" Margin="5,0,1,0" ToolTip="" Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}"> <btn:DropDownButton.Menu> <ContextMenu> <MenuItem Command="{Binding PlacementTarget.Tag.ExportHb, RelativeSource={RelativeSource AncestorType=ContextMenu}}" CommandParameter="{Binding}" Header='Honeybee Model *.hbjson'/> </ContextMenu> </btn:DropDownButton.Menu> </btn:DropDownButton> </StackPanel> </Grid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
内容的提问来源于stack exchange,提问作者konrad
相关产品推荐
相关产品推荐

