使用Caliburn Micro时DataGrid的ContextMenu调用ActivateItemAsync失效问题
Caliburn Micro调用ActivateItemAsync无法切换视图问题及解决方案
问题描述
我在项目中使用Caliburn Micro框架,此前调用ActivateItemAsync方法一直未出现问题,但现在该方法无法激活我的ActiveItem,相关代码如下:
首先是DashboardMainView代码:
<Grid > <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Ribbon ...> </Ribbon> <Grid Grid.Row="1" Background="#E8E8E8"> <ContentControl x:Name="ActiveItem" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> </ContentControl> </Grid>
对应的DashboardMainViewModel代码:
public class DashboardMainViewModel : Conductor<object> { private IDialogCoordinator dialogCoordinator; public DashboardMainViewModel(IDialogCoordinator instance) { this.dialogCoordinator = instance; ActivateItemAsync(new DashboardSummaryViewModel()); } public async Task Execution() { await ActivateItemAsync(new BasicExecutionViewModel(DialogCoordinator.Instance)); } }
上述代码运行正常,可成功激活BasicExecutionView,该视图内包含一个DataGrid和右键上下文菜单。问题出在右键操作环节:右键点击DataGrid弹出菜单,选中对应选项后应该激活新视图,但实际无响应,相关代码如下:
BasicExecutionView的XAML代码:
<Grid > <Viewbox Stretch="Fill"> <DataGrid x:Name="BasicExecutionGrid" CanUserSortColumns="True" IsReadOnly="True" CanUserAddRows="False" FontSize="11" Height ="800" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" AutoGeneratingColumn="BasicExecutionGrid_AutoGeneratingColumn"> <DataGrid.ColumnHeaderStyle> <Style TargetType="DataGridColumnHeader"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <TextBlock TextWrapping="Wrap" Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> </DataTemplate> </Setter.Value> </Setter> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="Background" Value="LightSteelBlue"/> <Setter Property="FontSize" Value="12"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Height" Value="45"/> </Style> </DataGrid.ColumnHeaderStyle> <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header="Details" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.ActivateCellDetailsView}" > </MenuItem> </ContextMenu> </DataGrid.ContextMenu> </DataGrid> </Viewbox> </Grid>
对应的BasicExecutionViewModel代码:
class BasicExecutionViewModel : Conductor<object> { private IDialogCoordinator dialogCoordinator; private RelayCommand activateCellDetailsView { get; set; } public BasicExecutionViewModel(IDialogCoordinator instance) { this.dialogCoordinator = instance; } public ICommand ActivateCellDetailsView { get { if (activateCellDetailsView == null) { activateCellDetailsView = new RelayCommand(async p=> await ActivateCellView()); } return activateCellDetailsView; } } public async Task ActivateCellView() { await ActivateItemAsync(new CellDetailsExecutionViewModel()); } }
调试发现代码可正常进入ActivateCellView()执行,输出窗口也显示ActiveItem已赋值为CellDetailsExecutionViewModel对象,但界面仍然显示BasicExecutionView。
修复方案
问题根因为Conductor<object>使用错误,修复步骤如下:
- 将DashboardMainViewModel的继承关系修改为:
DashboardMainViewModel: Conductor<object>.Collection.OneActive
- BasicExecutionViewModel也同步修改继承关系:
BasicExecutionViewModel: Conductor<object>.Collection.OneActive
- 修改
ActivateCellView()方法代码为:
public async Task ActivateCellView() { CellDetailsExecutionViewModel cellDetailsExecutionViewAcvtivate = new CellDetailsExecutionViewModel(); var parentConductor = (Conductor<object>.Collection.OneActive)(this.Parent); await parentConductor.ActivateItemAsync(cellDetailsExecutionViewAcvtivate); }
修改后功能运行正常。
内容的提问来源于stack exchange,提问作者Pepe
相关产品推荐
相关产品推荐

